Fork us on GitHub Follow us on Facebook Follow us on Twitter

Opened 10 years ago

Closed 10 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.

Change History (1)

comment:1 Changed 10 years ago by Jakub Jermář

Resolution: fixed
Status: newclosed

Fixed in changeset:head,310.

Note: See TracTickets for help on using tickets.