Subversion Repositories HelenOS

Rev

Rev 4728 | Rev 4731 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4728 Rev 4730
Line 121... Line 121...
121
/** Type definition of the ICMP reply timeout pointer.
121
/** Type definition of the ICMP reply timeout pointer.
122
 *  @see icmp_reply_timeout
122
 *  @see icmp_reply_timeout
123
 */
123
 */
124
typedef icmp_reply_timeout_t *  icmp_reply_timeout_ref;
124
typedef icmp_reply_timeout_t *  icmp_reply_timeout_ref;
125
 
125
 
-
 
126
/** ICMP reply timeout data.
-
 
127
 *  Used as a timeouting fibril argument.
-
 
128
 *  @see icmp_timeout_for_reply()
-
 
129
 */
-
 
130
struct icmp_reply_timeout{
-
 
131
    /** Reply data key.
-
 
132
     */
-
 
133
    int         reply_key;
-
 
134
    /** Timeout in microseconds.
-
 
135
     */
-
 
136
    suseconds_t timeout;
-
 
137
};
-
 
138
 
126
/** Processes the received ICMP packet.
139
/** Processes the received ICMP packet.
127
 *  Is used as an entry point from the underlying IP module.
140
 *  Is used as an entry point from the underlying IP module.
128
 *  Releases the packet on error.
141
 *  Releases the packet on error.
129
 *  @param device_id The device identifier. Ignored parameter.
142
 *  @param device_id The device identifier. Ignored parameter.
130
 *  @param packet The received packet. Input/output parameter.
143
 *  @param packet The received packet. Input/output parameter.
Line 250... Line 263...
250
 *  @returns EBADMEM if the echo_data parameter is NULL.
263
 *  @returns EBADMEM if the echo_data parameter is NULL.
251
 *  @returns ENOTCONN if no free identifier have been found.
264
 *  @returns ENOTCONN if no free identifier have been found.
252
 */
265
 */
253
int icmp_bind_free_id( icmp_echo_ref echo_data );
266
int icmp_bind_free_id( icmp_echo_ref echo_data );
254
 
267
 
255
/** ICMP reply timeout data.
-
 
256
 *  Used as a timeouting fibril argument.
-
 
257
 *  @see icmp_timeout_for_reply()
-
 
258
 */
-
 
259
struct icmp_reply_timeout{
-
 
260
    /** Reply data key.
-
 
261
     */
-
 
262
    int         reply_key;
-
 
263
    /** Timeout in microseconds.
-
 
264
     */
-
 
265
    suseconds_t timeout;
-
 
266
};
-
 
267
 
-
 
268
/** ICMP global data.
268
/** ICMP global data.
269
 */
269
 */
270
icmp_globals_t  icmp_globals;
270
icmp_globals_t  icmp_globals;
271
 
271
 
272
INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t );
272
INT_MAP_IMPLEMENT( icmp_replies, icmp_reply_t );
Line 377... Line 377...
377
    reply = malloc( sizeof( * reply ));
377
    reply = malloc( sizeof( * reply ));
378
    if( ! reply ){
378
    if( ! reply ){
379
        free( reply_timeout );
379
        free( reply_timeout );
380
        return icmp_release_and_return( packet, ENOMEM );
380
        return icmp_release_and_return( packet, ENOMEM );
381
    }
381
    }
-
 
382
    // prepare the timeouting thread
-
 
383
    fibril = fibril_create( icmp_timeout_for_reply, reply_timeout );
-
 
384
    if( ! fibril ){
-
 
385
        free( reply );
-
 
386
        free( reply_timeout );
-
 
387
        return icmp_release_and_return( packet, EPARTY );
-
 
388
    }
382
    reply_timeout->reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );
389
    reply_timeout->reply_key = ICMP_GET_REPLY_KEY( header->un.echo.identifier, header->un.echo.sequence_number );
383
    // timeout in microseconds
390
    // timeout in microseconds
384
    reply_timeout->timeout = timeout * 1000;
391
    reply_timeout->timeout = timeout * 1000;
385
    fibril_mutex_initialize( & reply->mutex );
392
    fibril_mutex_initialize( & reply->mutex );
386
    fibril_mutex_lock( & reply->mutex );
393
    fibril_mutex_lock( & reply->mutex );
387
    fibril_condvar_initialize( & reply->condvar );
394
    fibril_condvar_initialize( & reply->condvar );
-
 
395
    // start the timeouting fibril
-
 
396
    fibril_add_ready( fibril );
388
    index = icmp_replies_add( & icmp_globals.replies, reply_timeout->reply_key, reply );
397
    index = icmp_replies_add( & icmp_globals.replies, reply_timeout->reply_key, reply );
389
    if( index < 0 ){
398
    if( index < 0 ){
390
        free( reply );
399
        free( reply );
391
        free( reply_timeout );
-
 
392
        return icmp_release_and_return( packet, index );
400
        return icmp_release_and_return( packet, index );
393
    }
401
    }
394
    // start the timeouting thread
-
 
395
    fibril = fibril_create( icmp_timeout_for_reply, reply_timeout );
-
 
396
    if( ! fibril ){
-
 
397
        return EPARTY;
-
 
398
    }
-
 
399
    fibril_add_ready( fibril );
-
 
400
 
402
 
401
    // unlock the globals and wait for a reply
403
    // unlock the globals and wait for a reply
402
    fibril_rwlock_write_unlock( & icmp_globals.lock );
404
    fibril_rwlock_write_unlock( & icmp_globals.lock );
403
 
405
 
404
    // send the request
406
    // send the request
405
    icmp_send_packet( ICMP_ECHO, 0, packet, header, 0 );
407
    icmp_send_packet( ICMP_ECHO, 0, packet, header, 0 );
406
 
408
 
407
    // wait for a reply
409
    // wait for a reply
408
    fibril_condvar_wait( & reply->condvar, & reply->mutex );
410
    fibril_condvar_wait( & reply->condvar, & reply->mutex );
-
 
411
 
409
    // read the result
412
    // read the result
410
    result = reply->result;
413
    result = reply->result;
411
 
414
 
412
    // destroy the reply structure
415
    // destroy the reply structure
413
    fibril_mutex_unlock( & reply->mutex );
416
    fibril_mutex_unlock( & reply->mutex );