/* * tries to lock the entry (no r/w) */ int monitor_cache_trylock( Entry *e ) { monitor_entry_t *mp; assert( e != NULL ); assert( e->e_private != NULL ); mp = ( monitor_entry_t * )e->e_private; return ldap_pvt_thread_mutex_trylock( &mp->mp_mutex ); }
static long send_ldap_ber( Operation *op, BerElement *ber ) { Connection *conn = op->o_conn; ber_len_t bytes; long ret = 0; ber_get_option( ber, LBER_OPT_BER_BYTES_TO_WRITE, &bytes ); /* write only one pdu at a time - wait til it's our turn */ ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex ); if (( op->o_abandon && !op->o_cancel ) || !connection_valid( conn ) || conn->c_writers < 0 ) { ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); return 0; } conn->c_writers++; while ( conn->c_writers > 0 && conn->c_writing ) { ldap_pvt_thread_cond_wait( &conn->c_write1_cv, &conn->c_write1_mutex ); } /* connection was closed under us */ if ( conn->c_writers < 0 ) { /* we're the last waiter, let the closer continue */ if ( conn->c_writers == -1 ) ldap_pvt_thread_cond_signal( &conn->c_write1_cv ); conn->c_writers++; ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); return 0; } /* Our turn */ conn->c_writing = 1; /* write the pdu */ while( 1 ) { int err; /* lock the connection */ if ( ldap_pvt_thread_mutex_trylock( &conn->c_mutex )) { if ( !connection_valid(conn)) { ret = 0; break; } ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex ); if ( conn->c_writers < 0 ) { ret = 0; break; } continue; } if ( ber_flush2( conn->c_sb, ber, LBER_FLUSH_FREE_NEVER ) == 0 ) { ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); ret = bytes; break; } err = sock_errno(); /* * we got an error. if it's ewouldblock, we need to * wait on the socket being writable. otherwise, figure * it's a hard error and return. */ Debug( LDAP_DEBUG_CONNS, "ber_flush2 failed errno=%d reason=\"%s\"\n", err, sock_errstr(err), 0 ); if ( err != EWOULDBLOCK && err != EAGAIN ) { conn->c_writers--; conn->c_writing = 0; ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); connection_closing( conn, "connection lost on write" ); ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); return -1; } /* wait for socket to be write-ready */ ldap_pvt_thread_mutex_lock( &conn->c_write2_mutex ); conn->c_writewaiter = 1; slapd_set_write( conn->c_sd, 2 ); ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); ldap_pvt_thread_cond_wait( &conn->c_write2_cv, &conn->c_write2_mutex ); conn->c_writewaiter = 0; ldap_pvt_thread_mutex_unlock( &conn->c_write2_mutex ); ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex ); if ( conn->c_writers < 0 ) { ret = 0; break; } } conn->c_writing = 0; if ( conn->c_writers < 0 ) { conn->c_writers++; if ( !conn->c_writers ) ldap_pvt_thread_cond_signal( &conn->c_write1_cv ); } else { conn->c_writers--; ldap_pvt_thread_cond_signal( &conn->c_write1_cv ); } ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); return ret; }