Changeset 536ded4 in mainline
- Timestamp:
- 2010-02-17T21:46:48Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 91478aa
- Parents:
- e6b7b198
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/tl/icmp/icmp.c
re6b7b198 r536ded4 115 115 #define ICMP_GET_REPLY_KEY( id, sequence ) ((( id ) << 16 ) | ( sequence & 0xFFFF )) 116 116 117 /** Type definition of the ICMP reply timeout.118 * @see icmp_reply_timeout119 */120 typedef struct icmp_reply_timeout icmp_reply_timeout_t;121 122 /** Type definition of the ICMP reply timeout pointer.123 * @see icmp_reply_timeout124 */125 typedef icmp_reply_timeout_t * icmp_reply_timeout_ref;126 127 /** ICMP reply timeout data.128 * Used as a timeouting fibril argument.129 * @see icmp_timeout_for_reply()130 */131 struct icmp_reply_timeout{132 /** Reply data key.133 */134 int reply_key;135 /** Timeout in microseconds.136 */137 suseconds_t timeout;138 };139 140 117 /** Processes the received ICMP packet. 141 118 * Is used as an entry point from the underlying IP module. … … 255 232 int icmp_process_echo_reply( packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code ); 256 233 257 /** Tries to set the pending reply result as timeouted.258 * Sleeps the timeout period of time and then tries to obtain and set the pending reply result as timeouted and signals the reply result.259 * If the reply data are still present, the reply timeouted and the parent fibril is awaken.260 * The global lock is not released in this case to be reused by the parent fibril.261 * Should run in a searate fibril.262 * @param[in] data The icmp_reply_timeout structure.263 * @returns EOK on success.264 * @returns EINVAL if the data parameter is NULL.265 */266 int icmp_timeout_for_reply( void * data );267 268 234 /** Assigns a new identifier for the connection. 269 235 * Fills the echo data parameter with the assigned values. … … 304 270 } 305 271 306 int icmp_timeout_for_reply( void * data ){307 icmp_reply_ref reply;308 icmp_reply_timeout_ref timeout = data;309 310 if( ! timeout ){311 return EINVAL;312 }313 // sleep the given timeout314 async_usleep( timeout->timeout );315 // lock the globals316 fibril_rwlock_write_lock( & icmp_globals.lock );317 // find the pending reply318 reply = icmp_replies_find( & icmp_globals.replies, timeout->reply_key );319 if( reply ){320 // set the timeout result321 reply->result = ETIMEOUT;322 // notify the main fibril323 fibril_condvar_signal( & reply->condvar );324 }else{325 // unlock only if no reply326 fibril_rwlock_write_unlock( & icmp_globals.lock );327 }328 // release the timeout structure329 free( timeout );330 return EOK;331 }332 333 272 int icmp_echo( icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen ){ 334 273 ERROR_DECLARE; … … 339 278 uint8_t * data; 340 279 icmp_reply_ref reply; 341 i cmp_reply_timeout_ref reply_timeout;280 int reply_key; 342 281 int result; 343 282 int index; 344 fid_t fibril;345 283 346 284 if( addrlen <= 0 ){ … … 379 317 header->un.echo.sequence_number = sequence; 380 318 381 // prepare the reply and the reply timeout structures 382 reply_timeout = malloc( sizeof( * reply_timeout )); 383 if( ! reply_timeout ){ 384 return icmp_release_and_return( packet, ENOMEM ); 385 } 319 // prepare the reply structure 386 320 reply = malloc( sizeof( * reply )); 387 321 if( ! reply ){ 388 free( reply_timeout );389 322 return icmp_release_and_return( packet, ENOMEM ); 390 323 } 391 // prepare the timeouting thread392 fibril = fibril_create( icmp_timeout_for_reply, reply_timeout );393 if( ! fibril ){394 free( reply );395 free( reply_timeout );396 return icmp_release_and_return( packet, EPARTY );397 }398 reply_timeout->reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );399 // timeout in microseconds400 reply_timeout->timeout = timeout * 1000;401 324 fibril_mutex_initialize( & reply->mutex ); 402 325 fibril_mutex_lock( & reply->mutex ); 403 326 fibril_condvar_initialize( & reply->condvar ); 404 // start the timeouting fibril 405 fibril_add_ready( fibril ); 406 index = icmp_replies_add( & icmp_globals.replies, reply_timeout->reply_key, reply ); 327 reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number ); 328 index = icmp_replies_add( & icmp_globals.replies, reply_key, reply ); 407 329 if( index < 0 ){ 408 330 free( reply ); … … 417 339 418 340 // wait for a reply 419 fibril_condvar_wait( & reply->condvar, & reply->mutex ); 420 421 // read the result 422 result = reply->result; 341 // timeout in microseconds 342 if( ERROR_OCCURRED( fibril_condvar_wait_timeout( & reply->condvar, & reply->mutex, timeout * 1000 ))){ 343 result = ERROR_CODE; 344 345 // lock the globals again and clean up 346 fibril_rwlock_write_lock( & icmp_globals.lock ); 347 }else{ 348 // read the result 349 result = reply->result; 350 351 // release the reply structure 352 fibril_mutex_unlock( & reply->mutex ); 353 } 423 354 424 355 // destroy the reply structure 425 fibril_mutex_unlock( & reply->mutex );426 356 icmp_replies_exclude_index( & icmp_globals.replies, index ); 427 357 return result;
Note:
See TracChangeset
for help on using the changeset viewer.