Пример #1
0
/*
 * 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 );
}
Пример #2
0
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;
}