Changeset 71b00dcc in mainline for uspace/srv/net/socket/socket_client.c
- Timestamp:
- 2010-03-07T22:51:38Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 60ab6c3
- Parents:
- b5cbff4 (diff), 31c80a5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/socket/socket_client.c
rb5cbff4 r71b00dcc 75 75 /** Default timeout for connections in microseconds. 76 76 */ 77 #define SOCKET_CONNECT_TIMEOUT ( 1 * 1000 * 1000)77 #define SOCKET_CONNECT_TIMEOUT (1 * 1000 * 1000) 78 78 79 79 /** Maximum number of random attempts to find a new socket identifier before switching to the sequence. … … 97 97 /** Socket identifier. 98 98 */ 99 int 99 int socket_id; 100 100 /** Parent module phone. 101 101 */ 102 int 102 int phone; 103 103 /** Parent module service. 104 104 */ 105 services_t 105 services_t service; 106 106 /** Underlying protocol header size. 107 107 * Sending and receiving optimalization. 108 108 */ 109 size_t 109 size_t header_size; 110 110 /** Packet data fragment size. 111 111 * Sending optimalization. 112 112 */ 113 size_t 113 size_t data_fragment_size; 114 114 /** Sending safety lock. 115 115 * Locks the header_size and data_fragment_size attributes. 116 116 */ 117 fibril_rwlock_t 117 fibril_rwlock_t sending_lock; 118 118 /** Received packets queue. 119 119 */ 120 dyn_fifo_t 120 dyn_fifo_t received; 121 121 /** Received packets safety lock. 122 122 * Used for receiving and receive notifications. 123 123 * Locks the received attribute. 124 124 */ 125 fibril_mutex_t 125 fibril_mutex_t receive_lock; 126 126 /** Received packets signaling. 127 127 * Signaled upon receive notification. 128 128 */ 129 fibril_condvar_t 129 fibril_condvar_t receive_signal; 130 130 /** Waiting sockets queue. 131 131 */ 132 dyn_fifo_t 132 dyn_fifo_t accepted; 133 133 /** Waiting sockets safety lock. 134 134 * Used for accepting and accept notifications. 135 135 * Locks the accepted attribute. 136 136 */ 137 fibril_mutex_t 137 fibril_mutex_t accept_lock; 138 138 /** Waiting sockets signaling. 139 139 * Signaled upon accept notification. 140 140 */ 141 fibril_condvar_t 141 fibril_condvar_t accept_signal; 142 142 /** The number of blocked functions called. 143 143 * Used while waiting for the received packets or accepted sockets. 144 144 */ 145 int 145 int blocked; 146 146 }; 147 147 … … 150 150 * @see int_map.h 151 151 */ 152 INT_MAP_DECLARE( sockets, socket_t);152 INT_MAP_DECLARE(sockets, socket_t); 153 153 154 154 /** Socket client library global data. … … 157 157 /** TCP module phone. 158 158 */ 159 int 159 int tcp_phone; 160 160 /** UDP module phone. 161 161 */ 162 int 162 int udp_phone; 163 163 // /** The last socket identifier. 164 164 // */ … … 166 166 /** Active sockets. 167 167 */ 168 sockets_ref 168 sockets_ref sockets; 169 169 /** Safety lock. 170 170 * Write lock is used only for adding or removing sockets. … … 173 173 * No socket lock may be locked if this lock is unlocked. 174 174 */ 175 fibril_rwlock_t 175 fibril_rwlock_t lock; 176 176 } socket_globals = { 177 177 .tcp_phone = -1, … … 183 183 .writers = 0, 184 184 .waiters = { 185 .prev = & 186 .next = & 185 .prev = &socket_globals.lock.waiters, 186 .next = &socket_globals.lock.waiters 187 187 } 188 188 } 189 189 }; 190 190 191 INT_MAP_IMPLEMENT( sockets, socket_t);191 INT_MAP_IMPLEMENT(sockets, socket_t); 192 192 193 193 /** Returns the TCP module phone. … … 196 196 * @returns Other error codes as defined for the bind_service_timeout() function. 197 197 */ 198 static int socket_get_tcp_phone( void);198 static int socket_get_tcp_phone(void); 199 199 200 200 /** Returns the UDP module phone. … … 203 203 * @returns Other error codes as defined for the bind_service_timeout() function. 204 204 */ 205 static int socket_get_udp_phone( void);205 static int socket_get_udp_phone(void); 206 206 207 207 /** Returns the active sockets. 208 208 * @returns The active sockets. 209 209 */ 210 static sockets_ref socket_get_sockets( void);210 static sockets_ref socket_get_sockets(void); 211 211 212 212 /** Tries to find a new free socket identifier. … … 214 214 * @returns ELIMIT if there is no socket identifier available. 215 215 */ 216 static int socket_generate_new_id( void);216 static int socket_generate_new_id(void); 217 217 218 218 /** Default thread for new connections. … … 220 220 * @param[in] icall The initial message call structure. 221 221 */ 222 void socket_connection( ipc_callid_t iid, ipc_call_t * icall);222 void socket_connection(ipc_callid_t iid, ipc_call_t * icall); 223 223 224 224 /** Sends message to the socket parent module with specified data. … … 234 234 * @returns Other error codes as defined for the spcific message. 235 235 */ 236 int socket_send_data( int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength);236 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength); 237 237 238 238 /** Initializes a new socket specific data. … … 242 242 * @param[in] service The parent module service. 243 243 */ 244 void socket_initialize( socket_ref socket, int socket_id, int phone, services_t service);244 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service); 245 245 246 246 /** Clears and destroys the socket. 247 247 * @param[in] socket The socket to be destroyed. 248 248 */ 249 void socket_destroy( socket_ref socket);249 void socket_destroy(socket_ref socket); 250 250 251 251 /** Receives data via the socket. … … 263 263 * @returns Other error codes as defined for the spcific message. 264 264 */ 265 int recvfrom_core( ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen);265 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen); 266 266 267 267 /** Sends data via the socket to the remote address. … … 280 280 * @returns Other error codes as defined for the NET_SOCKET_SENDTO message. 281 281 */ 282 int sendto_core( ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen);283 284 static int socket_get_tcp_phone( void){285 if( socket_globals.tcp_phone < 0){286 socket_globals.tcp_phone = bind_service_timeout( SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT);282 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen); 283 284 static int socket_get_tcp_phone(void){ 285 if(socket_globals.tcp_phone < 0){ 286 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 0, 0, SERVICE_TCP, socket_connection, SOCKET_CONNECT_TIMEOUT); 287 287 } 288 288 return socket_globals.tcp_phone; 289 289 } 290 290 291 static int socket_get_udp_phone( void){292 if( socket_globals.udp_phone < 0){293 socket_globals.udp_phone = bind_service_timeout( SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT);291 static int socket_get_udp_phone(void){ 292 if(socket_globals.udp_phone < 0){ 293 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 0, 0, SERVICE_UDP, socket_connection, SOCKET_CONNECT_TIMEOUT); 294 294 } 295 295 return socket_globals.udp_phone; 296 296 } 297 297 298 static sockets_ref socket_get_sockets( void ){ 299 if( ! socket_globals.sockets ){ 300 socket_globals.sockets = ( sockets_ref ) malloc( sizeof( sockets_t )); 301 if( ! socket_globals.sockets ) return NULL; 302 if( sockets_initialize( socket_globals.sockets ) != EOK ){ 303 free( socket_globals.sockets ); 298 static sockets_ref socket_get_sockets(void){ 299 if(! socket_globals.sockets){ 300 socket_globals.sockets = (sockets_ref) malloc(sizeof(sockets_t)); 301 if(! socket_globals.sockets){ 302 return NULL; 303 } 304 if(sockets_initialize(socket_globals.sockets) != EOK){ 305 free(socket_globals.sockets); 304 306 socket_globals.sockets = NULL; 305 307 } 306 srand( 308 srand(task_get_id()); 307 309 } 308 310 return socket_globals.sockets; 309 311 } 310 312 311 static int socket_generate_new_id( void){312 sockets_ref 313 int 314 int 313 static int socket_generate_new_id(void){ 314 sockets_ref sockets; 315 int socket_id; 316 int count; 315 317 316 318 sockets = socket_get_sockets(); … … 318 320 // socket_id = socket_globals.last_id; 319 321 do{ 320 if( count < SOCKET_ID_TRIES){322 if(count < SOCKET_ID_TRIES){ 321 323 socket_id = rand() % INT_MAX; 322 324 ++ count; 323 }else if( count == SOCKET_ID_TRIES){325 }else if(count == SOCKET_ID_TRIES){ 324 326 socket_id = 1; 325 327 ++ count; 326 328 // only this branch for last_id 327 329 }else{ 328 if( socket_id < INT_MAX){330 if(socket_id < INT_MAX){ 329 331 ++ socket_id; 330 /* }else if( socket_globals.last_id){332 /* }else if(socket_globals.last_id){ 331 333 * socket_globals.last_id = 0; 332 334 * socket_id = 1; … … 335 337 } 336 338 } 337 }while( sockets_find( sockets, socket_id));339 }while(sockets_find(sockets, socket_id)); 338 340 // last_id = socket_id 339 341 return socket_id; 340 342 } 341 343 342 void socket_initialize( socket_ref socket, int socket_id, int phone, services_t service){344 void socket_initialize(socket_ref socket, int socket_id, int phone, services_t service){ 343 345 socket->socket_id = socket_id; 344 346 socket->phone = phone; 345 347 socket->service = service; 346 dyn_fifo_initialize( & socket->received, SOCKET_INITIAL_RECEIVED_SIZE);347 dyn_fifo_initialize( & socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);348 fibril_mutex_initialize( & socket->receive_lock);349 fibril_condvar_initialize( & socket->receive_signal);350 fibril_mutex_initialize( & socket->accept_lock);351 fibril_condvar_initialize( & socket->accept_signal);352 fibril_rwlock_initialize( & socket->sending_lock);353 } 354 355 void socket_connection( ipc_callid_t iid, ipc_call_t * icall){348 dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); 349 dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE); 350 fibril_mutex_initialize(&socket->receive_lock); 351 fibril_condvar_initialize(&socket->receive_signal); 352 fibril_mutex_initialize(&socket->accept_lock); 353 fibril_condvar_initialize(&socket->accept_signal); 354 fibril_rwlock_initialize(&socket->sending_lock); 355 } 356 357 void socket_connection(ipc_callid_t iid, ipc_call_t * icall){ 356 358 ERROR_DECLARE; 357 359 358 ipc_callid_t 359 ipc_call_t 360 socket_ref 361 362 while( true){363 364 callid = async_get_call( & call);365 switch( IPC_GET_METHOD( call)){360 ipc_callid_t callid; 361 ipc_call_t call; 362 socket_ref socket; 363 364 while(true){ 365 366 callid = async_get_call(&call); 367 switch(IPC_GET_METHOD(call)){ 366 368 case NET_SOCKET_RECEIVED: 367 369 case NET_SOCKET_ACCEPTED: 368 370 case NET_SOCKET_DATA_FRAGMENT_SIZE: 369 fibril_rwlock_read_lock( & socket_globals.lock);371 fibril_rwlock_read_lock(&socket_globals.lock); 370 372 // find the socket 371 socket = sockets_find( socket_get_sockets(), SOCKET_GET_SOCKET_ID( call));372 if( ! socket){373 socket = sockets_find(socket_get_sockets(), SOCKET_GET_SOCKET_ID(call)); 374 if(! socket){ 373 375 ERROR_CODE = ENOTSOCK; 374 376 }else{ 375 switch( IPC_GET_METHOD( call)){377 switch(IPC_GET_METHOD(call)){ 376 378 case NET_SOCKET_RECEIVED: 377 fibril_mutex_lock( & socket->receive_lock);379 fibril_mutex_lock(&socket->receive_lock); 378 380 // 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))){381 if(! ERROR_OCCURRED(dyn_fifo_push(&socket->received, SOCKET_GET_DATA_FRAGMENTS(call), SOCKET_MAX_RECEIVED_SIZE))){ 380 382 // signal the received packet 381 fibril_condvar_signal( & socket->receive_signal);383 fibril_condvar_signal(&socket->receive_signal); 382 384 } 383 fibril_mutex_unlock( & socket->receive_lock);385 fibril_mutex_unlock(&socket->receive_lock); 384 386 break; 385 387 case NET_SOCKET_ACCEPTED: 386 388 // push the new socket identifier 387 fibril_mutex_lock( & socket->accept_lock);388 if( ! ERROR_OCCURRED( dyn_fifo_push( & socket->accepted, 1, SOCKET_MAX_ACCEPTED_SIZE))){389 fibril_mutex_lock(&socket->accept_lock); 390 if(! ERROR_OCCURRED(dyn_fifo_push(&socket->accepted, 1, SOCKET_MAX_ACCEPTED_SIZE))){ 389 391 // signal the accepted socket 390 fibril_condvar_signal( & socket->accept_signal);392 fibril_condvar_signal(&socket->accept_signal); 391 393 } 392 fibril_mutex_unlock( & socket->accept_lock);394 fibril_mutex_unlock(&socket->accept_lock); 393 395 break; 394 396 default: 395 397 ERROR_CODE = ENOTSUP; 396 398 } 397 if(( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) > 0)398 && ( SOCKET_GET_DATA_FRAGMENT_SIZE( call ) != socket->data_fragment_size)){399 fibril_rwlock_write_lock( & socket->sending_lock);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); 400 402 // set the data fragment size 401 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( call);402 fibril_rwlock_write_unlock( & socket->sending_lock);403 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(call); 404 fibril_rwlock_write_unlock(&socket->sending_lock); 403 405 } 404 406 } 405 fibril_rwlock_read_unlock( & socket_globals.lock);407 fibril_rwlock_read_unlock(&socket_globals.lock); 406 408 break; 407 409 default: 408 410 ERROR_CODE = ENOTSUP; 409 411 } 410 ipc_answer_0( callid, ( ipcarg_t ) ERROR_CODE);411 } 412 } 413 414 int socket( int domain, int type, int protocol){412 ipc_answer_0(callid, (ipcarg_t) ERROR_CODE); 413 } 414 } 415 416 int socket(int domain, int type, int protocol){ 415 417 ERROR_DECLARE; 416 418 417 socket_ref 418 int 419 int 420 services_t 419 socket_ref socket; 420 int phone; 421 int socket_id; 422 services_t service; 421 423 422 424 // find the appropriate service 423 switch( domain){425 switch(domain){ 424 426 case PF_INET: 425 switch( type){427 switch(type){ 426 428 case SOCK_STREAM: 427 if( ! protocol ) protocol = IPPROTO_TCP; 428 switch( protocol ){ 429 if(! protocol){ 430 protocol = IPPROTO_TCP; 431 } 432 switch(protocol){ 429 433 case IPPROTO_TCP: 430 434 phone = socket_get_tcp_phone(); … … 436 440 break; 437 441 case SOCK_DGRAM: 438 if( ! protocol ) protocol = IPPROTO_UDP; 439 switch( protocol ){ 442 if(! protocol){ 443 protocol = IPPROTO_UDP; 444 } 445 switch(protocol){ 440 446 case IPPROTO_UDP: 441 447 phone = socket_get_udp_phone(); … … 455 461 return EPFNOSUPPORT; 456 462 } 457 if( phone < 0 ) return phone; 463 if(phone < 0){ 464 return phone; 465 } 458 466 // create a new socket structure 459 socket = ( socket_ref ) malloc( sizeof( socket_t )); 460 if( ! socket ) return ENOMEM; 461 bzero( socket, sizeof( * socket )); 462 fibril_rwlock_write_lock( & socket_globals.lock ); 467 socket = (socket_ref) malloc(sizeof(socket_t)); 468 if(! socket){ 469 return ENOMEM; 470 } 471 bzero(socket, sizeof(*socket)); 472 fibril_rwlock_write_lock(&socket_globals.lock); 463 473 // request a new socket 464 474 socket_id = socket_generate_new_id(); 465 if( socket_id <= 0){466 fibril_rwlock_write_unlock( & socket_globals.lock);467 free( socket);475 if(socket_id <= 0){ 476 fibril_rwlock_write_unlock(&socket_globals.lock); 477 free(socket); 468 478 return socket_id; 469 479 } 470 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))){471 fibril_rwlock_write_unlock( & socket_globals.lock);472 free( socket);480 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))){ 481 fibril_rwlock_write_unlock(&socket_globals.lock); 482 free(socket); 473 483 return ERROR_CODE; 474 484 } 475 485 // finish the new socket initialization 476 socket_initialize( socket, socket_id, phone, service);486 socket_initialize(socket, socket_id, phone, service); 477 487 // store the new socket 478 ERROR_CODE = sockets_add( socket_get_sockets(), socket_id, socket);479 fibril_rwlock_write_unlock( & socket_globals.lock);480 if( ERROR_CODE < 0){481 dyn_fifo_destroy( & socket->received);482 dyn_fifo_destroy( & socket->accepted);483 free( socket);484 async_msg_3( phone, NET_SOCKET_CLOSE, ( ipcarg_t ) socket_id, 0, service);488 ERROR_CODE = sockets_add(socket_get_sockets(), socket_id, socket); 489 fibril_rwlock_write_unlock(&socket_globals.lock); 490 if(ERROR_CODE < 0){ 491 dyn_fifo_destroy(&socket->received); 492 dyn_fifo_destroy(&socket->accepted); 493 free(socket); 494 async_msg_3(phone, NET_SOCKET_CLOSE, (ipcarg_t) socket_id, 0, service); 485 495 return ERROR_CODE; 486 496 } … … 489 499 } 490 500 491 int socket_send_data( int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength ){ 492 socket_ref socket; 493 aid_t message_id; 494 ipcarg_t result; 495 496 if( ! data ) return EBADMEM; 497 if( ! datalength ) return NO_DATA; 498 499 fibril_rwlock_read_lock( & socket_globals.lock ); 501 int socket_send_data(int socket_id, ipcarg_t message, ipcarg_t arg2, const void * data, size_t datalength){ 502 socket_ref socket; 503 aid_t message_id; 504 ipcarg_t result; 505 506 if(! data){ 507 return EBADMEM; 508 } 509 if(! datalength){ 510 return NO_DATA; 511 } 512 513 fibril_rwlock_read_lock(&socket_globals.lock); 500 514 // find the socket 501 socket = sockets_find( socket_get_sockets(), socket_id);502 if( ! socket){503 fibril_rwlock_read_unlock( & socket_globals.lock);515 socket = sockets_find(socket_get_sockets(), socket_id); 516 if(! socket){ 517 fibril_rwlock_read_unlock(&socket_globals.lock); 504 518 return ENOTSOCK; 505 519 } 506 520 // request the message 507 message_id = async_send_3( socket->phone, message, ( ipcarg_t ) socket->socket_id, arg2, socket->service, NULL);521 message_id = async_send_3(socket->phone, message, (ipcarg_t) socket->socket_id, arg2, socket->service, NULL); 508 522 // send the address 509 async_data_write_start( socket->phone, data, datalength ); 510 fibril_rwlock_read_unlock( & socket_globals.lock ); 511 async_wait_for( message_id, & result ); 512 return ( int ) result; 513 } 514 515 int bind( int socket_id, const struct sockaddr * my_addr, socklen_t addrlen ){ 516 if( addrlen <= 0 ) return EINVAL; 523 async_data_write_start(socket->phone, data, datalength); 524 fibril_rwlock_read_unlock(&socket_globals.lock); 525 async_wait_for(message_id, &result); 526 return (int) result; 527 } 528 529 int bind(int socket_id, const struct sockaddr * my_addr, socklen_t addrlen){ 530 if(addrlen <= 0){ 531 return EINVAL; 532 } 517 533 // send the address 518 return socket_send_data( socket_id, NET_SOCKET_BIND, 0, my_addr, ( size_t ) addrlen ); 519 } 520 521 int listen( int socket_id, int backlog ){ 522 socket_ref socket; 523 int result; 524 525 if( backlog <= 0 ) return EINVAL; 526 fibril_rwlock_read_lock( & socket_globals.lock ); 534 return socket_send_data(socket_id, NET_SOCKET_BIND, 0, my_addr, (size_t) addrlen); 535 } 536 537 int listen(int socket_id, int backlog){ 538 socket_ref socket; 539 int result; 540 541 if(backlog <= 0){ 542 return EINVAL; 543 } 544 fibril_rwlock_read_lock(&socket_globals.lock); 527 545 // find the socket 528 socket = sockets_find( socket_get_sockets(), socket_id);529 if( ! socket){530 fibril_rwlock_read_unlock( & socket_globals.lock);546 socket = sockets_find(socket_get_sockets(), socket_id); 547 if(! socket){ 548 fibril_rwlock_read_unlock(&socket_globals.lock); 531 549 return ENOTSOCK; 532 550 } 533 551 // request listen backlog change 534 result = ( int ) async_req_3_0( socket->phone, NET_SOCKET_LISTEN, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) backlog, socket->service);535 fibril_rwlock_read_unlock( & socket_globals.lock);552 result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, (ipcarg_t) socket->socket_id, (ipcarg_t) backlog, socket->service); 553 fibril_rwlock_read_unlock(&socket_globals.lock); 536 554 return result; 537 555 } 538 556 539 int accept( int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen ){ 540 socket_ref socket; 541 socket_ref new_socket; 542 aid_t message_id; 543 ipcarg_t ipc_result; 544 int result; 545 ipc_call_t answer; 546 547 if(( ! cliaddr ) || ( ! addrlen )) return EBADMEM; 548 549 fibril_rwlock_write_lock( & socket_globals.lock ); 557 int accept(int socket_id, struct sockaddr * cliaddr, socklen_t * addrlen){ 558 socket_ref socket; 559 socket_ref new_socket; 560 aid_t message_id; 561 ipcarg_t ipc_result; 562 int result; 563 ipc_call_t answer; 564 565 if((! cliaddr) || (! addrlen)){ 566 return EBADMEM; 567 } 568 569 fibril_rwlock_write_lock(&socket_globals.lock); 550 570 // find the socket 551 socket = sockets_find( socket_get_sockets(), socket_id);552 if( ! socket){553 fibril_rwlock_write_unlock( & socket_globals.lock);571 socket = sockets_find(socket_get_sockets(), socket_id); 572 if(! socket){ 573 fibril_rwlock_write_unlock(&socket_globals.lock); 554 574 return ENOTSOCK; 555 575 } 556 fibril_mutex_lock( & socket->accept_lock);576 fibril_mutex_lock(&socket->accept_lock); 557 577 // wait for an accepted socket 558 578 ++ socket->blocked; 559 while( dyn_fifo_value( & socket->accepted ) <= 0){560 fibril_rwlock_write_unlock( & socket_globals.lock);561 fibril_condvar_wait( & socket->accept_signal, & socket->accept_lock);579 while(dyn_fifo_value(&socket->accepted) <= 0){ 580 fibril_rwlock_write_unlock(&socket_globals.lock); 581 fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock); 562 582 // drop the accept lock to avoid deadlock 563 fibril_mutex_unlock( & socket->accept_lock);564 fibril_rwlock_write_lock( & socket_globals.lock);565 fibril_mutex_lock( & socket->accept_lock);583 fibril_mutex_unlock(&socket->accept_lock); 584 fibril_rwlock_write_lock(&socket_globals.lock); 585 fibril_mutex_lock(&socket->accept_lock); 566 586 } 567 587 -- socket->blocked; 568 588 569 589 // create a new scoket 570 new_socket = ( socket_ref ) malloc( sizeof( socket_t));571 if( ! new_socket){572 fibril_mutex_unlock( & socket->accept_lock);573 fibril_rwlock_write_unlock( & socket_globals.lock);590 new_socket = (socket_ref) malloc(sizeof(socket_t)); 591 if(! new_socket){ 592 fibril_mutex_unlock(&socket->accept_lock); 593 fibril_rwlock_write_unlock(&socket_globals.lock); 574 594 return ENOMEM; 575 595 } 576 bzero( new_socket, sizeof( * new_socket));596 bzero(new_socket, sizeof(*new_socket)); 577 597 socket_id = socket_generate_new_id(); 578 if( socket_id <= 0){579 fibril_mutex_unlock( & socket->accept_lock);580 fibril_rwlock_write_unlock( & socket_globals.lock);581 free( new_socket);598 if(socket_id <= 0){ 599 fibril_mutex_unlock(&socket->accept_lock); 600 fibril_rwlock_write_unlock(&socket_globals.lock); 601 free(new_socket); 582 602 return socket_id; 583 603 } 584 socket_initialize( new_socket, socket_id, socket->phone, socket->service);585 result = sockets_add( socket_get_sockets(), new_socket->socket_id, new_socket);586 if( result < 0){587 fibril_mutex_unlock( & socket->accept_lock);588 fibril_rwlock_write_unlock( & socket_globals.lock);589 free( new_socket);604 socket_initialize(new_socket, socket_id, socket->phone, socket->service); 605 result = sockets_add(socket_get_sockets(), new_socket->socket_id, new_socket); 606 if(result < 0){ 607 fibril_mutex_unlock(&socket->accept_lock); 608 fibril_rwlock_write_unlock(&socket_globals.lock); 609 free(new_socket); 590 610 return result; 591 611 } 592 612 593 613 // request accept 594 message_id = async_send_5( socket->phone, NET_SOCKET_ACCEPT, ( ipcarg_t ) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, & answer);614 message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, (ipcarg_t) socket->socket_id, 0, socket->service, 0, new_socket->socket_id, &answer); 595 615 // read address 596 ipc_data_read_start( socket->phone, cliaddr, * addrlen);597 fibril_rwlock_write_unlock( & socket_globals.lock);598 async_wait_for( message_id, & ipc_result);616 ipc_data_read_start(socket->phone, cliaddr, * addrlen); 617 fibril_rwlock_write_unlock(&socket_globals.lock); 618 async_wait_for(message_id, &ipc_result); 599 619 result = (int) ipc_result; 600 if( result > 0){601 if( result != socket_id){620 if(result > 0){ 621 if(result != socket_id){ 602 622 result = EINVAL; 603 623 } 604 624 // dequeue the accepted socket if successful 605 dyn_fifo_pop( & socket->accepted);625 dyn_fifo_pop(&socket->accepted); 606 626 // set address length 607 * addrlen = SOCKET_GET_ADDRESS_LENGTH( answer);608 new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer);609 }else if( result == ENOTSOCK){627 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 628 new_socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer); 629 }else if(result == ENOTSOCK){ 610 630 // empty the queue if no accepted sockets 611 while( dyn_fifo_pop( & socket->accepted ) > 0);612 } 613 fibril_mutex_unlock( & socket->accept_lock);631 while(dyn_fifo_pop(&socket->accepted) > 0); 632 } 633 fibril_mutex_unlock(&socket->accept_lock); 614 634 return result; 615 635 } 616 636 617 int connect( int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen ){ 618 if( ! serv_addr ) return EDESTADDRREQ; 619 if( ! addrlen ) return EDESTADDRREQ; 637 int connect(int socket_id, const struct sockaddr * serv_addr, socklen_t addrlen){ 638 if(! serv_addr){ 639 return EDESTADDRREQ; 640 } 641 if(! addrlen){ 642 return EDESTADDRREQ; 643 } 620 644 // send the address 621 return socket_send_data( socket_id, NET_SOCKET_CONNECT, 0, serv_addr, addrlen);622 } 623 624 int closesocket( int socket_id){645 return socket_send_data(socket_id, NET_SOCKET_CONNECT, 0, serv_addr, addrlen); 646 } 647 648 int closesocket(int socket_id){ 625 649 ERROR_DECLARE; 626 650 627 socket_ref 628 629 fibril_rwlock_write_lock( & socket_globals.lock);630 socket = sockets_find( socket_get_sockets(), socket_id);631 if( ! socket){632 fibril_rwlock_write_unlock( & socket_globals.lock);651 socket_ref socket; 652 653 fibril_rwlock_write_lock(&socket_globals.lock); 654 socket = sockets_find(socket_get_sockets(), socket_id); 655 if(! socket){ 656 fibril_rwlock_write_unlock(&socket_globals.lock); 633 657 return ENOTSOCK; 634 658 } 635 if( socket->blocked){636 fibril_rwlock_write_unlock( & socket_globals.lock);659 if(socket->blocked){ 660 fibril_rwlock_write_unlock(&socket_globals.lock); 637 661 return EINPROGRESS; 638 662 } 639 663 // request close 640 ERROR_PROPAGATE(( int ) async_req_3_0( socket->phone, NET_SOCKET_CLOSE, ( ipcarg_t ) socket->socket_id, 0, socket->service));664 ERROR_PROPAGATE((int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, (ipcarg_t) socket->socket_id, 0, socket->service)); 641 665 // free the socket structure 642 socket_destroy( socket);643 fibril_rwlock_write_unlock( & socket_globals.lock);666 socket_destroy(socket); 667 fibril_rwlock_write_unlock(&socket_globals.lock); 644 668 return EOK; 645 669 } 646 670 647 void socket_destroy( socket_ref socket){648 int 671 void socket_destroy(socket_ref socket){ 672 int accepted_id; 649 673 650 674 // destroy all accepted sockets 651 while(( accepted_id = dyn_fifo_pop( & socket->accepted )) >= 0){652 socket_destroy( sockets_find( socket_get_sockets(), accepted_id));653 } 654 dyn_fifo_destroy( & socket->received);655 dyn_fifo_destroy( & socket->accepted);656 sockets_exclude( socket_get_sockets(), socket->socket_id);657 } 658 659 int send( int socket_id, void * data, size_t datalength, int flags){675 while((accepted_id = dyn_fifo_pop(&socket->accepted)) >= 0){ 676 socket_destroy(sockets_find(socket_get_sockets(), accepted_id)); 677 } 678 dyn_fifo_destroy(&socket->received); 679 dyn_fifo_destroy(&socket->accepted); 680 sockets_exclude(socket_get_sockets(), socket->socket_id); 681 } 682 683 int send(int socket_id, void * data, size_t datalength, int flags){ 660 684 // without the address 661 return sendto_core( NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0 ); 662 } 663 664 int sendto( int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen ){ 665 if( ! toaddr ) return EDESTADDRREQ; 666 if( ! addrlen ) return EDESTADDRREQ; 685 return sendto_core(NET_SOCKET_SEND, socket_id, data, datalength, flags, NULL, 0); 686 } 687 688 int sendto(int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 689 if(! toaddr){ 690 return EDESTADDRREQ; 691 } 692 if(! addrlen){ 693 return EDESTADDRREQ; 694 } 667 695 // with the address 668 return sendto_core( NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen ); 669 } 670 671 int sendto_core( ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen ){ 672 socket_ref socket; 673 aid_t message_id; 674 ipcarg_t result; 675 size_t fragments; 676 ipc_call_t answer; 677 678 if( ! data ) return EBADMEM; 679 if( ! datalength ) return NO_DATA; 680 fibril_rwlock_read_lock( & socket_globals.lock ); 696 return sendto_core(NET_SOCKET_SENDTO, socket_id, data, datalength, flags, toaddr, addrlen); 697 } 698 699 int sendto_core(ipcarg_t message, int socket_id, const void * data, size_t datalength, int flags, const struct sockaddr * toaddr, socklen_t addrlen){ 700 socket_ref socket; 701 aid_t message_id; 702 ipcarg_t result; 703 size_t fragments; 704 ipc_call_t answer; 705 706 if(! data){ 707 return EBADMEM; 708 } 709 if(! datalength){ 710 return NO_DATA; 711 } 712 fibril_rwlock_read_lock(&socket_globals.lock); 681 713 // find socket 682 socket = sockets_find( socket_get_sockets(), socket_id);683 if( ! socket){684 fibril_rwlock_read_unlock( & socket_globals.lock);714 socket = sockets_find(socket_get_sockets(), socket_id); 715 if(! socket){ 716 fibril_rwlock_read_unlock(&socket_globals.lock); 685 717 return ENOTSOCK; 686 718 } 687 fibril_rwlock_read_lock( & socket->sending_lock);719 fibril_rwlock_read_lock(&socket->sending_lock); 688 720 // compute data fragment count 689 if( socket->data_fragment_size > 0){690 fragments = ( datalength + socket->header_size) / socket->data_fragment_size;691 if(( datalength + socket->header_size ) % socket->data_fragment_size) ++ fragments;721 if(socket->data_fragment_size > 0){ 722 fragments = (datalength + socket->header_size) / socket->data_fragment_size; 723 if((datalength + socket->header_size) % socket->data_fragment_size) ++ fragments; 692 724 }else{ 693 725 fragments = 1; 694 726 } 695 727 // request send 696 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);728 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); 697 729 // send the address if given 698 if(( ! toaddr ) || ( async_data_write_start( socket->phone, toaddr, addrlen ) == EOK)){699 if( fragments == 1){730 if((! toaddr) || (async_data_write_start(socket->phone, toaddr, addrlen) == EOK)){ 731 if(fragments == 1){ 700 732 // send all if only one fragment 701 async_data_write_start( socket->phone, data, datalength);733 async_data_write_start(socket->phone, data, datalength); 702 734 }else{ 703 735 // send the first fragment 704 async_data_write_start( socket->phone, data, socket->data_fragment_size - socket->header_size);705 data = (( const uint8_t * ) data) + socket->data_fragment_size - socket->header_size;736 async_data_write_start(socket->phone, data, socket->data_fragment_size - socket->header_size); 737 data = ((const uint8_t *) data) + socket->data_fragment_size - socket->header_size; 706 738 // send the middle fragments 707 while(( -- fragments ) > 1){708 async_data_write_start( socket->phone, data, socket->data_fragment_size);709 data = (( const uint8_t * ) data) + socket->data_fragment_size;739 while((-- fragments) > 1){ 740 async_data_write_start(socket->phone, data, socket->data_fragment_size); 741 data = ((const uint8_t *) data) + socket->data_fragment_size; 710 742 } 711 743 // send the last fragment 712 async_data_write_start( socket->phone, data, ( datalength + socket->header_size ) % socket->data_fragment_size);713 } 714 } 715 async_wait_for( message_id, & result);716 if(( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) > 0)717 && ( SOCKET_GET_DATA_FRAGMENT_SIZE( answer ) != socket->data_fragment_size)){744 async_data_write_start(socket->phone, data, (datalength + socket->header_size) % socket->data_fragment_size); 745 } 746 } 747 async_wait_for(message_id, &result); 748 if((SOCKET_GET_DATA_FRAGMENT_SIZE(answer) > 0) 749 && (SOCKET_GET_DATA_FRAGMENT_SIZE(answer) != socket->data_fragment_size)){ 718 750 // set the data fragment size 719 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE( answer);720 } 721 fibril_rwlock_read_unlock( & socket->sending_lock);722 fibril_rwlock_read_unlock( & socket_globals.lock);723 return ( int) result;724 } 725 726 int recv( int socket_id, void * data, size_t datalength, int flags){751 socket->data_fragment_size = SOCKET_GET_DATA_FRAGMENT_SIZE(answer); 752 } 753 fibril_rwlock_read_unlock(&socket->sending_lock); 754 fibril_rwlock_read_unlock(&socket_globals.lock); 755 return (int) result; 756 } 757 758 int recv(int socket_id, void * data, size_t datalength, int flags){ 727 759 // without the address 728 return recvfrom_core( NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL ); 729 } 730 731 int recvfrom( int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen ){ 732 if( ! fromaddr ) return EBADMEM; 733 if( ! addrlen ) return NO_DATA; 760 return recvfrom_core(NET_SOCKET_RECV, socket_id, data, datalength, flags, NULL, NULL); 761 } 762 763 int recvfrom(int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 764 if(! fromaddr){ 765 return EBADMEM; 766 } 767 if(! addrlen){ 768 return NO_DATA; 769 } 734 770 // with the address 735 return recvfrom_core( NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen ); 736 } 737 738 int recvfrom_core( ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen ){ 739 socket_ref socket; 740 aid_t message_id; 741 ipcarg_t ipc_result; 742 int result; 743 size_t fragments; 744 size_t * lengths; 745 size_t index; 746 ipc_call_t answer; 747 748 if( ! data ) return EBADMEM; 749 if( ! datalength ) return NO_DATA; 750 if( fromaddr && ( ! addrlen )) return EINVAL; 751 fibril_rwlock_read_lock( & socket_globals.lock ); 771 return recvfrom_core(NET_SOCKET_RECVFROM, socket_id, data, datalength, flags, fromaddr, addrlen); 772 } 773 774 int recvfrom_core(ipcarg_t message, int socket_id, void * data, size_t datalength, int flags, struct sockaddr * fromaddr, socklen_t * addrlen){ 775 socket_ref socket; 776 aid_t message_id; 777 ipcarg_t ipc_result; 778 int result; 779 size_t fragments; 780 size_t * lengths; 781 size_t index; 782 ipc_call_t answer; 783 784 if(! data){ 785 return EBADMEM; 786 } 787 if(! datalength){ 788 return NO_DATA; 789 } 790 if(fromaddr && (! addrlen)){ 791 return EINVAL; 792 } 793 fibril_rwlock_read_lock(&socket_globals.lock); 752 794 // find the socket 753 socket = sockets_find( socket_get_sockets(), socket_id);754 if( ! socket){755 fibril_rwlock_read_unlock( & socket_globals.lock);795 socket = sockets_find(socket_get_sockets(), socket_id); 796 if(! socket){ 797 fibril_rwlock_read_unlock(&socket_globals.lock); 756 798 return ENOTSOCK; 757 799 } 758 fibril_mutex_lock( & socket->receive_lock);800 fibril_mutex_lock(&socket->receive_lock); 759 801 // wait for a received packet 760 802 ++ socket->blocked; 761 while(( result = dyn_fifo_value( & socket->received )) <= 0){762 fibril_rwlock_read_unlock( & socket_globals.lock);763 fibril_condvar_wait( & socket->receive_signal, & socket->receive_lock);803 while((result = dyn_fifo_value(&socket->received)) <= 0){ 804 fibril_rwlock_read_unlock(&socket_globals.lock); 805 fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock); 764 806 // drop the receive lock to avoid deadlock 765 fibril_mutex_unlock( & socket->receive_lock);766 fibril_rwlock_read_lock( & socket_globals.lock);767 fibril_mutex_lock( & socket->receive_lock);807 fibril_mutex_unlock(&socket->receive_lock); 808 fibril_rwlock_read_lock(&socket_globals.lock); 809 fibril_mutex_lock(&socket->receive_lock); 768 810 } 769 811 -- socket->blocked; 770 fragments = ( size_t) result;812 fragments = (size_t) result; 771 813 // prepare lengths if more fragments 772 if( fragments > 1){773 lengths = ( size_t * ) malloc( sizeof( size_t ) * fragments + sizeof( size_t));774 if( ! lengths){775 fibril_mutex_unlock( & socket->receive_lock);776 fibril_rwlock_read_unlock( & socket_globals.lock);814 if(fragments > 1){ 815 lengths = (size_t *) malloc(sizeof(size_t) * fragments + sizeof(size_t)); 816 if(! lengths){ 817 fibril_mutex_unlock(&socket->receive_lock); 818 fibril_rwlock_read_unlock(&socket_globals.lock); 777 819 return ENOMEM; 778 820 } 779 821 // request packet data 780 message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, 0, socket->service, ( ipcarg_t ) flags, & answer);822 message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer); 781 823 // read the address if desired 782 if(( ! fromaddr ) || ( async_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK)){824 if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){ 783 825 // read the fragment lengths 784 if( async_data_read_start( socket->phone, lengths, sizeof( int ) * ( fragments + 1 )) == EOK){785 if( lengths[ fragments ] <= datalength){826 if(async_data_read_start(socket->phone, lengths, sizeof(int) * (fragments + 1)) == EOK){ 827 if(lengths[fragments] <= datalength){ 786 828 // read all fragments if long enough 787 for( index = 0; index < fragments; ++ index){788 async_data_read_start( socket->phone, data, lengths[ index ]);789 data = (( uint8_t * ) data ) + lengths[ index];829 for(index = 0; index < fragments; ++ index){ 830 async_data_read_start(socket->phone, data, lengths[index]); 831 data = ((uint8_t *) data) + lengths[index]; 790 832 } 791 833 } 792 834 } 793 835 } 794 free( lengths);836 free(lengths); 795 837 }else{ 796 838 // request packet data 797 message_id = async_send_4( socket->phone, message, ( ipcarg_t ) socket->socket_id, 0, socket->service, ( ipcarg_t ) flags, & answer);839 message_id = async_send_4(socket->phone, message, (ipcarg_t) socket->socket_id, 0, socket->service, (ipcarg_t) flags, &answer); 798 840 // read the address if desired 799 if(( ! fromaddr ) || ( async_data_read_start( socket->phone, fromaddr, * addrlen ) == EOK)){841 if((! fromaddr) || (async_data_read_start(socket->phone, fromaddr, * addrlen) == EOK)){ 800 842 // read all if only one fragment 801 async_data_read_start( socket->phone, data, datalength);802 } 803 } 804 async_wait_for( message_id, & ipc_result);843 async_data_read_start(socket->phone, data, datalength); 844 } 845 } 846 async_wait_for(message_id, &ipc_result); 805 847 result = (int) ipc_result; 806 848 // if successful 807 if( result == EOK){849 if(result == EOK){ 808 850 // dequeue the received packet 809 dyn_fifo_pop( & socket->received);851 dyn_fifo_pop(&socket->received); 810 852 // return read data length 811 result = SOCKET_GET_READ_DATA_LENGTH( answer);853 result = SOCKET_GET_READ_DATA_LENGTH(answer); 812 854 // set address length 813 if( fromaddr && addrlen ) * addrlen = SOCKET_GET_ADDRESS_LENGTH( answer ); 814 } 815 fibril_mutex_unlock( & socket->receive_lock ); 816 fibril_rwlock_read_unlock( & socket_globals.lock ); 855 if(fromaddr && addrlen){ 856 *addrlen = SOCKET_GET_ADDRESS_LENGTH(answer); 857 } 858 } 859 fibril_mutex_unlock(&socket->receive_lock); 860 fibril_rwlock_read_unlock(&socket_globals.lock); 817 861 return result; 818 862 } 819 863 820 int getsockopt( int socket_id, int level, int optname, void * value, size_t * optlen ){ 821 socket_ref socket; 822 aid_t message_id; 823 ipcarg_t result; 824 825 if( !( value && optlen )) return EBADMEM; 826 if( !( * optlen )) return NO_DATA; 827 fibril_rwlock_read_lock( & socket_globals.lock ); 864 int getsockopt(int socket_id, int level, int optname, void * value, size_t * optlen){ 865 socket_ref socket; 866 aid_t message_id; 867 ipcarg_t result; 868 869 if(!(value && optlen)){ 870 return EBADMEM; 871 } 872 if(!(*optlen)){ 873 return NO_DATA; 874 } 875 fibril_rwlock_read_lock(&socket_globals.lock); 828 876 // find the socket 829 socket = sockets_find( socket_get_sockets(), socket_id);830 if( ! socket){831 fibril_rwlock_read_unlock( & socket_globals.lock);877 socket = sockets_find(socket_get_sockets(), socket_id); 878 if(! socket){ 879 fibril_rwlock_read_unlock(&socket_globals.lock); 832 880 return ENOTSOCK; 833 881 } 834 882 // request option value 835 message_id = async_send_3( socket->phone, NET_SOCKET_GETSOCKOPT, ( ipcarg_t ) socket->socket_id, ( ipcarg_t ) optname, socket->service, NULL);883 message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, (ipcarg_t) socket->socket_id, (ipcarg_t) optname, socket->service, NULL); 836 884 // read the length 837 if( async_data_read_start( socket->phone, optlen, sizeof( * optlen )) == EOK){885 if(async_data_read_start(socket->phone, optlen, sizeof(*optlen)) == EOK){ 838 886 // read the value 839 async_data_read_start( socket->phone, value, * optlen);840 } 841 fibril_rwlock_read_unlock( & socket_globals.lock);842 async_wait_for( message_id, & result);843 return ( int) result;844 } 845 846 int setsockopt( int socket_id, int level, int optname, const void * value, size_t optlen){887 async_data_read_start(socket->phone, value, * optlen); 888 } 889 fibril_rwlock_read_unlock(&socket_globals.lock); 890 async_wait_for(message_id, &result); 891 return (int) result; 892 } 893 894 int setsockopt(int socket_id, int level, int optname, const void * value, size_t optlen){ 847 895 // send the value 848 return socket_send_data( socket_id, NET_SOCKET_SETSOCKOPT, ( ipcarg_t ) optname, value, optlen);896 return socket_send_data(socket_id, NET_SOCKET_SETSOCKOPT, (ipcarg_t) optname, value, optlen); 849 897 850 898 }
Note:
See TracChangeset
for help on using the changeset viewer.