Changeset ede63e4 in mainline for uspace/srv/net/socket
- Timestamp:
- 2010-01-04T23:25:48Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- eac9722
- Parents:
- 1a0fb3f8
- Location:
- uspace/srv/net/socket
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/socket/socket_client.c
r1a0fb3f8 rede63e4 40 40 #include <async.h> 41 41 #include <fibril_synch.h> 42 #include <limits.h> 43 #include <stdlib.h> 42 44 43 45 #include <ipc/services.h> … … 74 76 */ 75 77 #define SOCKET_CONNECT_TIMEOUT ( 1 * 1000 * 1000 ) 78 79 /** Maximum number of random attempts to find a new socket identifier before switching to the sequence. 80 */ 81 #define SOCKET_ID_TRIES 100 76 82 77 83 /** Type definition of the socket specific data. … … 155 161 */ 156 162 int udp_phone; 163 // /** The last socket identifier. 164 // */ 165 // int last_id; 157 166 /** Active sockets. 158 167 */ … … 168 177 .tcp_phone = -1, 169 178 .udp_phone = -1, 179 // .last_id = 0, 170 180 .sockets = NULL, 171 181 .lock = { … … 199 209 */ 200 210 static sockets_ref socket_get_sockets( void ); 211 212 /** Tries to find a new free socket identifier. 213 * @returns The new socket identifier. 214 * @returns ELIMIT if there is no socket identifier available. 215 */ 216 static int socket_generate_new_id( void ); 201 217 202 218 /** Default thread for new connections. … … 288 304 socket_globals.sockets = NULL; 289 305 } 306 srand( task_get_id()); 290 307 } 291 308 return socket_globals.sockets; 309 } 310 311 static int socket_generate_new_id( void ){ 312 sockets_ref sockets; 313 int socket_id; 314 int count; 315 316 sockets = socket_get_sockets(); 317 count = 0; 318 // socket_id = socket_globals.last_id; 319 do{ 320 if( count < SOCKET_ID_TRIES ){ 321 socket_id = rand() % INT_MAX; 322 ++ count; 323 }else if( count == SOCKET_ID_TRIES ){ 324 socket_id = 1; 325 ++ count; 326 // only this branch for last_id 327 }else{ 328 if( socket_id < INT_MAX ){ 329 ++ socket_id; 330 /* }else if( socket_globals.last_id ){ 331 * socket_globals.last_id = 0; 332 * socket_id = 1; 333 */ }else{ 334 return ELIMIT; 335 } 336 } 337 }while( sockets_find( sockets, socket_id )); 338 // last_id = socket_id 339 return socket_id; 292 340 } 293 341 … … 311 359 ipc_call_t call; 312 360 socket_ref socket; 313 socket_ref new_socket;314 361 315 362 while( true ){ … … 318 365 switch( IPC_GET_METHOD( call )){ 319 366 case NET_SOCKET_RECEIVED: 320 fibril_rwlock_read_lock( & socket_globals.lock );321 // find the socket322 socket = sockets_find( socket_get_sockets(), SOCKET_GET_SOCKET_ID( call ));323 if( ! socket ){324 ERROR_CODE = ENOTSOCK;325 }else{326 fibril_mutex_lock( & socket->receive_lock );327 // push the number of received packet fragments328 if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->received, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_MAX_RECEIVED_SIZE ))){329 // signal the received packet330 fibril_condvar_signal( & socket->receive_signal );331 }332 fibril_mutex_unlock( & socket->receive_lock );333 }334 fibril_rwlock_read_unlock( & socket_globals.lock );335 break;336 367 case NET_SOCKET_ACCEPTED: 337 fibril_rwlock_read_lock( & socket_globals.lock );338 // find the socket339 socket = sockets_find( socket_get_sockets(), SOCKET_GET_SOCKET_ID( call ));340 if( ! socket ){341 ERROR_CODE = ENOTSOCK;342 }else{343 // create a new scoket344 new_socket = ( socket_ref ) malloc( sizeof( socket_t ));345 if( ! new_socket ){346 ERROR_CODE = ENOMEM;347 }else{348 bzero( new_socket, sizeof( * new_socket ));349 socket_initialize( new_socket, SOCKET_GET_NEW_SOCKET_ID( call ), socket->phone, socket->service );350 ERROR_CODE = sockets_add( socket_get_sockets(), new_socket->socket_id, new_socket );351 if( ERROR_CODE < 0 ){352 free( new_socket );353 }else{354 // push the new socket identifier355 fibril_mutex_lock( & socket->accept_lock );356 if( ERROR_OCCURRED( dyn_fifo_push( & socket->accepted, new_socket->socket_id, SOCKET_MAX_ACCEPTED_SIZE ))){357 sockets_exclude( socket_get_sockets(), new_socket->socket_id );358 }else{359 // signal the accepted socket360 fibril_condvar_signal( & socket->accept_signal );361 }362 fibril_mutex_unlock( & socket->accept_lock );363 ERROR_CODE = EOK;364 }365 }366 }367 fibril_rwlock_read_unlock( & socket_globals.lock );368 break;369 368 case NET_SOCKET_DATA_FRAGMENT_SIZE: 370 369 fibril_rwlock_read_lock( & socket_globals.lock ); … … 374 373 ERROR_CODE = ENOTSOCK; 375 374 }else{ 376 fibril_rwlock_write_lock( & socket->sending_lock ); 377 // set the data fragment size 378 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( call ); 379 fibril_rwlock_write_unlock( & socket->sending_lock ); 380 ERROR_CODE = EOK; 375 switch( IPC_GET_METHOD( call )){ 376 case NET_SOCKET_RECEIVED: 377 fibril_mutex_lock( & socket->receive_lock ); 378 // push the number of received packet fragments 379 if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->received, SOCKET_GET_DATA_FRAGMENTS( call ), SOCKET_MAX_RECEIVED_SIZE ))){ 380 // signal the received packet 381 fibril_condvar_signal( & socket->receive_signal ); 382 } 383 fibril_mutex_unlock( & socket->receive_lock ); 384 break; 385 case NET_SOCKET_ACCEPTED: 386 // push the new socket identifier 387 fibril_mutex_lock( & socket->accept_lock ); 388 if( ERROR_OCCURRED( dyn_fifo_push( & socket->accepted, SOCKET_GET_NEW_SOCKET_ID( call ), SOCKET_MAX_ACCEPTED_SIZE ))){ 389 sockets_exclude( socket_get_sockets(), SOCKET_GET_NEW_SOCKET_ID( call )); 390 }else{ 391 // signal the accepted socket 392 fibril_condvar_signal( & socket->accept_signal ); 393 } 394 fibril_mutex_unlock( & socket->accept_lock ); 395 break; 396 default: 397 ERROR_CODE = ENOTSUP; 398 } 399 if(( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) > 0 ) 400 && ( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) != socket->data_fragment_size )){ 401 fibril_rwlock_write_lock( & socket->sending_lock ); 402 // set the data fragment size 403 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( call ); 404 fibril_rwlock_write_unlock( & socket->sending_lock ); 405 } 381 406 } 382 407 fibril_rwlock_read_unlock( & socket_globals.lock ); 383 break;384 408 default: 385 409 ERROR_CODE = ENOTSUP; … … 396 420 int socket_id; 397 421 services_t service; 422 int count; 398 423 399 424 // find the appropriate service … … 437 462 if( ! socket ) return ENOMEM; 438 463 bzero( socket, sizeof( * socket )); 464 count = 0; 465 fibril_rwlock_write_lock( & socket_globals.lock ); 439 466 // request a new socket 440 if( ERROR_OCCURRED(( int ) async_req_3_3( phone, NET_SOCKET, 0, 0, service, ( ipcarg_t * ) & socket_id, ( ipcarg_t * ) & socket->data_fragment_size, ( ipcarg_t * ) & socket->header_size ))){ 467 socket_id = socket_generate_new_id(); 468 if( socket_id <= 0 ){ 469 fibril_rwlock_write_unlock( & socket_globals.lock ); 470 free( socket ); 471 return socket_id; 472 } 473 if( ERROR_OCCURRED(( int ) async_req_3_3( phone, NET_SOCKET, socket_id, 0, service, NULL, ( ipcarg_t * ) & socket->data_fragment_size, ( ipcarg_t * ) & socket->header_size ))){ 474 fibril_rwlock_write_unlock( & socket_globals.lock ); 441 475 free( socket ); 442 476 return ERROR_CODE; … … 445 479 socket_initialize( socket, socket_id, phone, service ); 446 480 // store the new socket 447 fibril_rwlock_write_lock( & socket_globals.lock );448 481 ERROR_CODE = sockets_add( socket_get_sockets(), socket_id, socket ); 449 482 fibril_rwlock_write_unlock( & socket_globals.lock ); … … 509 542 int accept( int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen ){ 510 543 socket_ref socket; 544 socket_ref new_socket; 511 545 aid_t message_id; 512 546 int result; … … 515 549 if(( ! cliaddr ) || ( ! addrlen )) return EBADMEM; 516 550 517 fibril_rwlock_ read_lock( & socket_globals.lock );551 fibril_rwlock_write_lock( & socket_globals.lock ); 518 552 // find the socket 519 553 socket = sockets_find( socket_get_sockets(), socket_id ); 520 554 if( ! socket ){ 521 fibril_rwlock_ read_unlock( & socket_globals.lock );555 fibril_rwlock_write_unlock( & socket_globals.lock ); 522 556 return ENOTSOCK; 523 557 } … … 526 560 ++ socket->blocked; 527 561 while( dyn_fifo_value( & socket->accepted ) <= 0 ){ 528 fibril_rwlock_ read_unlock( & socket_globals.lock );562 fibril_rwlock_write_unlock( & socket_globals.lock ); 529 563 fibril_condvar_wait( & socket->accept_signal, & socket->accept_lock ); 530 fibril_rwlock_ read_lock( & socket_globals.lock );564 fibril_rwlock_write_lock( & socket_globals.lock ); 531 565 } 532 566 -- socket->blocked; 567 568 // create a new scoket 569 new_socket = ( socket_ref ) malloc( sizeof( socket_t )); 570 if( ! new_socket ){ 571 fibril_mutex_unlock( & socket->accept_lock ); 572 fibril_rwlock_write_unlock( & socket_globals.lock ); 573 return ENOMEM; 574 } 575 bzero( new_socket, sizeof( * new_socket )); 576 socket_id = socket_generate_new_id(); 577 if( socket_id <= 0 ){ 578 fibril_mutex_unlock( & socket->accept_lock ); 579 fibril_rwlock_write_unlock( & socket_globals.lock ); 580 free( new_socket ); 581 return socket_id; 582 } 583 socket_initialize( new_socket, socket_id, socket->phone, socket->service ); 584 result = sockets_add( socket_get_sockets(), new_socket->socket_id, new_socket ); 585 if( result < 0 ){ 586 fibril_mutex_unlock( & socket->accept_lock ); 587 fibril_rwlock_write_unlock( & socket_globals.lock ); 588 free( new_socket ); 589 return result; 590 } 591 533 592 // request accept 534 message_id = async_send_ 3( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, 0, socket->service, & answer );593 message_id = async_send_5( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, & answer ); 535 594 // read address 536 async_data_read_start( socket->phone, cliaddr, * addrlen );537 fibril_rwlock_ read_unlock( & socket_globals.lock );595 ipc_data_read_start( socket->phone, cliaddr, * addrlen ); 596 fibril_rwlock_write_unlock( & socket_globals.lock ); 538 597 async_wait_for( message_id, ( ipcarg_t * ) & result ); 539 598 if( result > 0 ){ 599 if( result != socket_id ){ 600 result = EINVAL; 601 } 540 602 // dequeue the accepted socket if successful 541 603 dyn_fifo_pop( & socket->accepted ); 542 604 // set address length 543 605 * addrlen = SOCKET_GET_ADDRESS_LENGTH( answer ); 606 new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer ); 544 607 }else if( result == ENOTSOCK ){ 545 608 // empty the queue if no accepted sockets … … 609 672 ipcarg_t result; 610 673 size_t fragments; 674 ipc_call_t answer; 611 675 612 676 if( ! data ) return EBADMEM; … … 621 685 fibril_rwlock_read_lock( & socket->sending_lock ); 622 686 // compute data fragment count 623 fragments = ( datalength + socket->header_size ) / socket->data_fragment_size; 624 if(( datalength + socket->header_size ) % socket->data_fragment_size ) ++ fragments; 687 if( socket->data_fragment_size > 0 ){ 688 fragments = ( datalength + socket->header_size ) / socket->data_fragment_size; 689 if(( datalength + socket->header_size ) % socket->data_fragment_size ) ++ fragments; 690 }else{ 691 fragments = 1; 692 } 625 693 // request send 626 message_id = async_send_5( socket->phone, message, ( ipcarg_t ) socket->socket_id, socket->data_fragment_size, socket->service, ( ipcarg_t ) flags, fragments, NULL);694 message_id = async_send_5( socket->phone, message, ( ipcarg_t ) socket->socket_id, ( fragments == 1 ? datalength : socket->data_fragment_size ), socket->service, ( ipcarg_t ) flags, fragments, & answer ); 627 695 // send the address if given 628 696 if(( ! toaddr ) || ( async_data_write_start( socket->phone, toaddr, addrlen ) == EOK )){ … … 643 711 } 644 712 } 713 async_wait_for( message_id, & result ); 714 if(( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) > 0 ) 715 && ( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) != socket->data_fragment_size )){ 716 // set the data fragment size 717 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer ); 718 } 645 719 fibril_rwlock_read_unlock( & socket->sending_lock ); 646 720 fibril_rwlock_read_unlock( & socket_globals.lock ); 647 async_wait_for( message_id, & result );648 721 return ( int ) result; 649 722 } -
uspace/srv/net/socket/socket_core.c
r1a0fb3f8 rede63e4 35 35 */ 36 36 37 #include <limits.h> 38 #include <stdlib.h> 39 37 40 #include "../err.h" 38 41 … … 51 54 52 55 #include "socket_core.h" 56 57 /** Maximum number of random attempts to find a new socket identifier before switching to the sequence. 58 */ 59 #define SOCKET_ID_TRIES 100 53 60 54 61 /** Bound port sockets. … … 94 101 */ 95 102 int socket_port_add_core( socket_port_ref socket_port, socket_core_ref socket, const char * key, size_t key_length ); 103 104 /** Tries to find a new free socket identifier. 105 * @param[in] local_sockets The local sockets to be searched. 106 * @param[in] positive A value indicating whether a positive identifier is requested. A negative identifier is requested if set to false. 107 * @returns The new socket identifier. 108 * @returns ELIMIT if there is no socket identifier available. 109 */ 110 static int socket_generate_new_id( socket_cores_ref local_sockets, int positive ); 96 111 97 112 INT_MAP_IMPLEMENT( socket_cores, socket_core_t ); … … 230 245 } 231 246 247 248 static int socket_generate_new_id( socket_cores_ref local_sockets, int positive ){ 249 int socket_id; 250 int count; 251 252 count = 0; 253 // socket_id = socket_globals.last_id; 254 do{ 255 if( count < SOCKET_ID_TRIES ){ 256 socket_id = rand() % INT_MAX; 257 ++ count; 258 }else if( count == SOCKET_ID_TRIES ){ 259 socket_id = 1; 260 ++ count; 261 // only this branch for last_id 262 }else{ 263 if( socket_id < INT_MAX ){ 264 ++ socket_id; 265 /* }else if( socket_globals.last_id ){ 266 * socket_globals.last_id = 0; 267 * socket_id = 1; 268 */ }else{ 269 return ELIMIT; 270 } 271 } 272 }while( socket_cores_find( local_sockets, (( positive ? 1 : -1 ) * socket_id ))); 273 // last_id = socket_id 274 return socket_id; 275 } 276 232 277 int socket_create( socket_cores_ref local_sockets, int app_phone, void * specific_data, int * socket_id ){ 233 278 ERROR_DECLARE; … … 235 280 socket_core_ref socket; 236 281 int res; 237 238 if( ! socket_id ) return EBADMEM; 282 int positive; 283 284 if( ! socket_id ) return EINVAL; 285 // store the socket 286 if( * socket_id <= 0 ){ 287 positive = ( * socket_id == 0 ); 288 * socket_id = socket_generate_new_id( local_sockets, positive ); 289 if( * socket_id <= 0 ){ 290 return * socket_id; 291 } 292 if( ! positive ){ 293 * socket_id *= -1; 294 } 295 }else if( socket_cores_find( local_sockets, * socket_id )){ 296 return EEXIST; 297 } 239 298 socket = ( socket_core_ref ) malloc( sizeof( * socket )); 240 299 if( ! socket ) return ENOMEM; … … 254 313 return ERROR_CODE; 255 314 } 256 // get a next free socket number 257 socket->socket_id = socket_cores_count( local_sockets ) + 1; 258 // store the socket 315 socket->socket_id = * socket_id; 259 316 res = socket_cores_add( local_sockets, socket->socket_id, socket ); 260 317 if( res < 0 ){ … … 264 321 return res; 265 322 } 266 // return the socket identifier267 * socket_id = socket->socket_id;268 323 return EOK; 269 324 } -
uspace/srv/net/socket/socket_core.h
r1a0fb3f8 rede63e4 177 177 * @param[in] app_phone The application phone. 178 178 * @param[in] specific_data The socket specific data. 179 * @param[ out] socket_id The new socket identifier.180 * @returns EOK on success. 181 * @returns E BADMEMif the socket_id parameter is NULL.179 * @param[in,out] socket_id The new socket identifier. A new identifier is chosen if set to zero (0) or negative. A negative identifier is chosen if set to negative. 180 * @returns EOK on success. 181 * @returns EINVAL if the socket_id parameter is NULL. 182 182 * @returns ENOMEM if there is not enough memory left. 183 183 */ -
uspace/srv/net/socket/socket_messages.h
r1a0fb3f8 rede63e4 142 142 #define SOCKET_GET_OPT_LEVEL( call ) ( int ) IPC_GET_ARG2( call ) 143 143 144 /** Sets the address length in the message answer.145 * @param[out] answer The message answer structure.146 */147 #define SOCKET_SET_ADDRESS_LENGTH( answer ) ( socklen_t * ) & IPC_GET_ARG2( answer )148 149 /** Returns the address length message parameter.150 * @param[in] call The message call structure.151 */152 #define SOCKET_GET_ADDRESS_LENGTH( call ) ( socklen_t ) IPC_GET_ARG2( call )153 154 144 /** Returns the data fragment size message parameter. 155 145 * @param[in] call The message call structure. … … 161 151 */ 162 152 #define SOCKET_SET_DATA_FRAGMENT_SIZE( answer ) ( size_t * ) & IPC_GET_ARG2( answer ) 153 154 /** Sets the address length in the message answer. 155 * @param[out] answer The message answer structure. 156 */ 157 #define SOCKET_SET_ADDRESS_LENGTH( answer ) ( socklen_t * ) & IPC_GET_ARG3( answer ) 158 159 /** Returns the address length message parameter. 160 * @param[in] call The message call structure. 161 */ 162 #define SOCKET_GET_ADDRESS_LENGTH( call ) ( socklen_t ) IPC_GET_ARG3( call ) 163 163 164 164 /** Sets the header size in the message answer.
Note:
See TracChangeset
for help on using the changeset viewer.