Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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;
}