Opened 15 years ago
Closed 15 years ago
#195 closed defect (fixed)
Potential deadlock in recvfrom_core()
Reported by: | Jakub Jermář | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | 0.4.2 |
Component: | helenos/net/socket | Version: | mainline |
Keywords: | Cc: | ||
Blocker for: | Depends on: | ||
See also: |
Description
Consider the following snippet from socket_clinet.c::recvfrom_core():
fibril_rwlock_read_lock( & socket_globals.lock ); socket = sockets_find( socket_get_sockets(), socket_id ); if( ! socket ){ fibril_rwlock_read_unlock( & socket_globals.lock ); return ENOTSOCK; } fibril_mutex_lock( & socket->receive_lock ); ++ socket->blocked; while(( result = dyn_fifo_value( & socket->received )) <= 0 ){ fibril_rwlock_read_unlock( & socket_globals.lock ); fibril_condvar_wait( & socket->receive_signal, & socket->receive_lock ); fibril_rwlock_read_lock( & socket_globals.lock ); }
The code uses two locking schemes for acquiring:
A) socket_globals.lock
B) socket→receive_lock
The first locking scheme (A → B) is used before the code reaches the while loop;
The second locking scheme (B → A) is used after the wakeup from fibril_condvar_wait(), when B is attempted while still holding A.
Looks like B should be dropped after waking up from fibril_condvar_wait() and reacquired after A is locked one line below.
Note:
See TracTickets
for help on using tickets.
Fixed in changeset:head,310.