예제 #1
0
int
ldap_int_thread_initialize( void )
{
	LDAP_ENSURE( pthread_mutexattr_init( &mutex_attr_errorcheck ) == 0 );
	LDAP_ENSURE( pthread_mutexattr_settype( &mutex_attr_errorcheck, PTHREAD_MUTEX_ERRORCHECK ) == 0);
	return 0;
}
예제 #2
0
static __attribute__((constructor)) void ldap_debug_lock_init(void)
{
	pthread_mutexattr_t mutexattr;
	LDAP_ENSURE(pthread_mutexattr_init(&mutexattr) == 0);
	LDAP_ENSURE(pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE) == 0);
	LDAP_ENSURE(pthread_mutex_init(&debug_mutex, &mutexattr) == 0);
}
예제 #3
0
void ldap_debug_lock(void) {
#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
	LDAP_ENSURE(pthread_mutex_lock(&debug_mutex) == 0);
#else
	LDAP_ENSURE(ldap_pvt_thread_mutex_recursive_lock(&debug_mutex) == 0);
#endif /* HAVE_PTHREAD_MUTEX_RECURSIVE */

	debug_lockdeep += 1;
}
예제 #4
0
void ldap_debug_unlock(void) {
	if (debug_lockdeep > 0) {
		debug_lockdeep -= 1;
		if (debug_lockdeep == 0
				&& debug_autoflush >= (AUTOFLUSH_ENABLED | AUTOFLUSH_STUFFED)
				&& debug_lastc == '\n')
			debug_flush();
	}

#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
	LDAP_ENSURE(pthread_mutex_unlock(&debug_mutex) == 0);
#else
	LDAP_ENSURE(ldap_pvt_thread_mutex_recursive_unlock(&debug_mutex) == 0);
#endif /* HAVE_PTHREAD_MUTEX_RECURSIVE */
}
예제 #5
0
int ldap_pvt_thread_rdwr_wunlock( ldap_pvt_thread_rdwr_t *rw )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_rwlock_unlock( rw ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #6
0
int ldap_pvt_thread_rdwr_wtrylock( ldap_pvt_thread_rdwr_t *rw )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_rwlock_trywrlock( rw ) );
	LDAP_ENSURE(rc == 0 || rc == EBUSY);
	LDAP_JITTER(25);
	return rc;
}
예제 #7
0
int
ldap_int_thread_destroy( void )
{
#ifdef HAVE_PTHREAD_KILL_OTHER_THREADS_NP
	/* LinuxThreads: kill clones */
	pthread_kill_other_threads_np();
#endif
	LDAP_ENSURE( pthread_mutexattr_destroy( &mutex_attr_errorcheck ) == 0);
	return 0;
}
예제 #8
0
int
ldap_pvt_thread_cond_broadcast( ldap_pvt_thread_cond_t *cond )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_cond_broadcast( cond ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #9
0
int
ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_rwlock_init( rw, NULL ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #10
0
int
ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
{
	int rc;
	LDAP_JITTER(25);
	rc = pthread_setspecific( key, data );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #11
0
int
ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
{
	int rc;
	LDAP_JITTER(25);
	rc = pthread_key_delete( key );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #12
0
int
ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
{
	int rc;
	LDAP_JITTER(25);
	rc = pthread_key_create( key, NULL );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #13
0
int
ldap_pvt_thread_mutex_unlock( ldap_pvt_thread_mutex_t *mutex )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_mutex_unlock( mutex ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #14
0
int
ldap_pvt_thread_mutex_init( ldap_pvt_thread_mutex_t *mutex )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_mutex_init( mutex, ldap_mutex_attr() ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #15
0
int
ldap_pvt_thread_cond_init( ldap_pvt_thread_cond_t *cond )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_cond_init( cond, LDAP_INT_THREAD_CONDATTR_DEFAULT ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #16
0
int
ldap_pvt_thread_cond_wait( ldap_pvt_thread_cond_t *cond,
		      ldap_pvt_thread_mutex_t *mutex )
{
	int rc;
	LDAP_JITTER(25);
	rc = ERRVAL( pthread_cond_wait( cond, mutex ) );
	LDAP_ENSURE(rc == 0);
	LDAP_JITTER(25);
	return rc;
}
예제 #17
0
int ldap_debug_trylock(void) {
#ifdef HAVE_PTHREAD_MUTEX_RECURSIVE
	int rc = pthread_mutex_trylock(&debug_mutex);
#else
	int rc = ldap_pvt_thread_mutex_recursive_trylock(&debug_mutex);
#endif /* HAVE_PTHREAD_MUTEX_RECURSIVE */

	LDAP_ENSURE(rc == 0 || rc == EBUSY);
	if (rc == 0)
		debug_lockdeep += 1;
	return rc;
}
예제 #18
0
static int sssvlv_op_search(
	Operation		*op,
	SlapReply		*rs)
{
	slap_overinst			*on			= (slap_overinst *)op->o_bd->bd_info;
	sssvlv_info				*si			= on->on_bi.bi_private;
	int						rc			= SLAP_CB_CONTINUE;
	int	ok, need_unlock = 0;
	sort_ctrl *sc;
	PagedResultsState *ps;
	vlv_ctrl *vc;
	int sess_id;

	if ( op->o_ctrlflag[sss_cid] <= SLAP_CONTROL_IGNORED ) {
		if ( op->o_ctrlflag[vlv_cid] > SLAP_CONTROL_IGNORED ) {
			sort_op so; memset(&so, 0, sizeof(so));
			so.so_vlv_rc = LDAP_VLV_SSS_MISSING;
			so.so_vlv = op->o_ctrlflag[vlv_cid];
			LDAPControl *ctrls[2];
			rc = pack_vlv_response_control( op, rs, &so, ctrls );
			if ( rc == LDAP_SUCCESS ) {
				ctrls[1] = NULL;
				slap_add_ctrls( op, rs, ctrls );
			}
			rs->sr_err = LDAP_VLV_ERROR;
			rs->sr_text = "Sort control is required with VLV";
			goto leave;
		}
		/* Not server side sort so just continue */
		return SLAP_CB_CONTINUE;
	}

	Debug(LDAP_DEBUG_TRACE,
		"==> sssvlv_search: <%s> %s, control flag: %d\n",
		op->o_req_dn.bv_val, op->ors_filterstr.bv_val,
		op->o_ctrlflag[sss_cid]);

	sc = op->o_controls[sss_cid];
	if ( sc->sc_nkeys > si->svi_max_keys ) {
		rs->sr_text = "Too many sort keys";
		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
		goto leave;
	}

	ps = ( op->o_pagedresults > SLAP_CONTROL_IGNORED ) ?
		(PagedResultsState*)(op->o_pagedresults_state) : NULL;
	vc = op->o_ctrlflag[vlv_cid] > SLAP_CONTROL_IGNORED ?
		op->o_controls[vlv_cid] : NULL;

	if ( ps && vc ) {
		rs->sr_text = "VLV incompatible with PagedResults";
		rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
		goto leave;
	}

	ldap_pvt_thread_mutex_lock( &sort_conns_mutex );
	ok = need_unlock = 1;
	sort_op *so = NULL;

	/* Is there already a sort running on this conn? */
	sess_id = find_session_by_context( si->svi_max_percon, op->o_conn->c_conn_idx, vc ? vc->vc_context : NO_VC_CONTEXT, ps ? ps->ps_cookie : NO_PS_COOKIE );
	if ( sess_id >= 0 ) {
		so = sort_conns[op->o_conn->c_conn_idx][sess_id];
		if (so->so_running) {
			/* another thread is handling, response busy to client */
			ok = 0;
			so = NULL;
		} else {
			/* Is it a continuation of a VLV search? */
			if ( !vc || so->so_vlv <= SLAP_CONTROL_IGNORED ||
					vc->vc_context != so->so_vcontext ) {
				/* Is it a continuation of a paged search? */
				if ( !ps || so->so_paged <= SLAP_CONTROL_IGNORED ||
					op->o_conn->c_pagedresults_state.ps_cookie != ps->ps_cookie ) {
					ok = 0;
				} else if ( !ps->ps_size ) {
					/* Abandoning current request */
					ok = 0;
					so->so_nentries = 0;
					rs->sr_err = LDAP_SUCCESS;
				}
			}
			if (( vc && so->so_paged > SLAP_CONTROL_IGNORED ) ||
					( ps && so->so_vlv > SLAP_CONTROL_IGNORED )) {
				/* changed from paged to vlv or vice versa, abandon */
				ok = 0;
				so->so_nentries = 0;
				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			}
			if ( ok ) {
				/* occupy before mutex unlock */
				so->so_running = 1;
			}
		}
	/* Are there too many running overall? */
	} else if ( si->svi_num >= si->svi_max ) {
		ok = 0;
	} else if ( ( sess_id = find_next_session(si->svi_max_percon, op->o_conn->c_conn_idx ) ) < 0 ) {
		ok = 0;
	} else {
		/* OK, this connection going a sort running as the sess_id */
	}

	if (! ok || so != NULL) {
		assert(need_unlock != 0);
		ldap_pvt_thread_mutex_unlock( &sort_conns_mutex );
		need_unlock = 0;
	}

	if ( ok ) {
		/* If we're a global overlay, this check got bypassed */
		if ( !op->ors_limit && limits_check( op, rs )) {
			if (need_unlock) {
				ldap_pvt_thread_mutex_unlock( &sort_conns_mutex );
				need_unlock = 0;
			}
			if (so)
				free_sort_op( op->o_conn, so );
			return rs->sr_err;
		}
		/* are we continuing a VLV search? */
		if ( so && vc && vc->vc_context ) {
			assert(need_unlock == 0);
			so->so_ctrl = sc;
			send_list( op, rs, so );
			send_result( op, rs, so );
			rc = LDAP_SUCCESS;
		/* are we continuing a paged search? */
		} else if ( so && ps && ps->ps_cookie ) {
			assert(need_unlock == 0);
			so->so_ctrl = sc;
			send_page( op, rs, so );
			send_result( op, rs, so );
			rc = LDAP_SUCCESS;
		} else {
			/* Install serversort response callback to handle a new search */
			assert(need_unlock != 0);
			assert(so == NULL);

			so = ch_calloc( 1, sizeof(sort_op));
			slap_callback *cb = op->o_tmpcalloc( 1, sizeof(slap_callback),
				op->o_tmpmemctx );
			LDAP_ENSURE(so != NULL && cb != NULL); /* FIXME: LDAP_OTHER */

			cb->sc_response		= sssvlv_op_response;
			cb->sc_next			= op->o_callback;
			cb->sc_private		= so;

			assert(so->so_tree == NULL);
			so->so_ctrl = sc;
			so->so_info = si;
			if ( ps ) {
				so->so_paged = op->o_pagedresults;
				so->so_page_size = ps->ps_size;
				op->o_pagedresults = SLAP_CONTROL_IGNORED;
				assert(so->so_page_size != 0);
			} else {
				if ( vc ) {
					so->so_vlv = op->o_ctrlflag[vlv_cid];
					assert(so->so_vlv_target == 0);
					assert(so->so_vlv_rc == 0);
					assert(so->so_vlv != SLAP_CONTROL_NONE);
				} else {
					assert(so->so_vlv == SLAP_CONTROL_NONE);
				}
			}
			so->so_session = sess_id;
			so->so_vlv = op->o_ctrlflag[vlv_cid];
			so->so_vcontext = (size_t)so;
			assert(so->so_nentries == 0);
			op->o_callback = cb;

			assert(sess_id >= 0);
			so->so_running = 1;
			sort_conns[op->o_conn->c_conn_idx][sess_id] = so;
			si->svi_num++;
			ldap_pvt_thread_mutex_unlock( &sort_conns_mutex );
			need_unlock = 0;
		}
		assert(need_unlock == 0);
	} else {
		assert(need_unlock == 0);
		if ( so && !so->so_nentries ) {
			free_sort_op( op->o_conn, so );
		} else {
			rs->sr_text = "Other sort requests already in progress";
			rs->sr_err = LDAP_BUSY;
		}
leave:
		assert(need_unlock == 0);
		rc = rs->sr_err;
		send_ldap_result( op, rs );
	}

	assert(need_unlock == 0);
	return rc;
}
예제 #19
0
static __attribute__((constructor)) void ldap_debug_lock_init(void)
{
	LDAP_ENSURE(ldap_pvt_thread_mutex_recursive_init(&debug_mutex) == 0);
}