Opened 16 years ago
Closed 16 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.