int bdb_tool_entry_close( BackendDB *be ) { if ( bdb_tool_info ) { slapd_shutdown = 1; #ifdef USE_TRICKLE ldap_pvt_thread_mutex_lock( &bdb_tool_trickle_mutex ); /* trickle thread may not have started yet */ while ( !bdb_tool_trickle_active ) ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end, &bdb_tool_trickle_mutex ); ldap_pvt_thread_cond_signal( &bdb_tool_trickle_cond ); while ( bdb_tool_trickle_active ) ldap_pvt_thread_cond_wait( &bdb_tool_trickle_cond_end, &bdb_tool_trickle_mutex ); ldap_pvt_thread_mutex_unlock( &bdb_tool_trickle_mutex ); #endif if ( bdb_tool_threads > 1 ) { ldap_pvt_thread_mutex_lock( &bdb_tool_index_mutex ); /* There might still be some threads starting */ while ( bdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, &bdb_tool_index_mutex ); } bdb_tool_index_tcount = bdb_tool_threads - 1; ldap_pvt_thread_cond_broadcast( &bdb_tool_index_cond_work ); /* Make sure all threads are stopped */ while ( bdb_tool_index_tcount > 0 ) { ldap_pvt_thread_cond_wait( &bdb_tool_index_cond_main, &bdb_tool_index_mutex ); } ldap_pvt_thread_mutex_unlock( &bdb_tool_index_mutex ); ch_free( bdb_tool_index_threads ); ch_free( bdb_tool_index_rec ); bdb_tool_index_tcount = bdb_tool_threads - 1; } bdb_tool_info = NULL; slapd_shutdown = 0; } if( eh.bv.bv_val ) { ch_free( eh.bv.bv_val ); eh.bv.bv_val = NULL; } if( cursor ) { cursor->c_close( cursor ); cursor = NULL; } #ifdef BDB_TOOL_IDL_CACHING bdb_tool_idl_flush( be ); #endif if( nholes ) { unsigned i; fprintf( stderr, "Error, entries missing!\n"); for (i=0; i<nholes; i++) { fprintf(stderr, " entry %ld: %s\n", holes[i].id, holes[i].dn.bv_val); } return -1; } return 0; }
static long send_ldap_ber( Operation *op, BerElement *ber ) { Connection *conn = op->o_conn; ber_len_t bytes; long ret = 0; char *close_reason; 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_pool_idle( &connection_pool ); ldap_pvt_thread_cond_wait( &conn->c_write1_cv, &conn->c_write1_mutex ); ldap_pvt_thread_pool_unidle( &connection_pool ); } /* 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; if ( ber_flush2( conn->c_sb, ber, LBER_FLUSH_FREE_NEVER ) == 0 ) { 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 ) { close_reason = "connection lost on write"; fail: conn->c_writers--; conn->c_writing = 0; ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); ldap_pvt_thread_mutex_lock( &conn->c_mutex ); connection_closing( conn, close_reason ); ldap_pvt_thread_mutex_unlock( &conn->c_mutex ); return -1; } /* wait for socket to be write-ready */ conn->c_writewaiter = 1; ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex ); ldap_pvt_thread_pool_idle( &connection_pool ); slap_writewait_play( op ); err = slapd_wait_writer( conn->c_sd ); conn->c_writewaiter = 0; ldap_pvt_thread_pool_unidle( &connection_pool ); ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex ); /* 0 is timeout, so we close it. * -1 is an error, close it. */ if ( err <= 0 ) { if ( err == 0 ) close_reason = "writetimeout"; else close_reason = "connection lost on writewait"; goto fail; } 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; }