19 * connection_activity - handle the request operation op on connection
20 * conn. This routine figures out what kind of operation it is and
21 * calls the appropriate stub to handle it.
25 connection_operation( void *arg_v )
27 struct co_arg *arg = arg_v;
30 pthread_mutex_lock( &arg->co_conn->c_opsmutex );
31 arg->co_conn->c_opsinitiated++;
32 pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
34 pthread_mutex_lock( &ops_mutex );
36 pthread_mutex_unlock( &ops_mutex );
38 switch ( arg->co_op->o_tag ) {
40 do_bind( arg->co_conn, arg->co_op );
44 case LDAP_REQ_UNBIND_30:
47 do_unbind( arg->co_conn, arg->co_op );
51 do_add( arg->co_conn, arg->co_op );
55 case LDAP_REQ_DELETE_30:
58 do_delete( arg->co_conn, arg->co_op );
62 do_modrdn( arg->co_conn, arg->co_op );
66 do_modify( arg->co_conn, arg->co_op );
69 case LDAP_REQ_COMPARE:
70 do_compare( arg->co_conn, arg->co_op );
74 do_search( arg->co_conn, arg->co_op );
78 case LDAP_REQ_ABANDON_30:
80 case LDAP_REQ_ABANDON:
81 do_abandon( arg->co_conn, arg->co_op );
85 Debug( LDAP_DEBUG_ANY, "unknown request 0x%lx\n",
86 arg->co_op->o_tag, 0, 0 );
90 pthread_mutex_lock( &arg->co_conn->c_opsmutex );
91 arg->co_conn->c_opscompleted++;
92 slap_op_delete( &arg->co_conn->c_ops, arg->co_op );
93 pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
97 pthread_mutex_lock( &ops_mutex );
99 pthread_mutex_unlock( &ops_mutex );
101 pthread_mutex_lock( &active_threads_mutex );
103 if( active_threads < 1 ) {
104 pthread_cond_signal(&active_threads_cond);
106 pthread_mutex_unlock( &active_threads_mutex );
117 unsigned long tag, len;
122 if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
124 Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
129 if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
130 != LDAP_TAG_MESSAGE ) {
131 Debug( LDAP_DEBUG_TRACE,
132 "ber_get_next on fd %d failed errno %d (%s)\n",
133 conn->c_sb.sb_sd, errno, errno > -1 && errno < sys_nerr ?
134 sys_errlist[errno] : "unknown" );
135 Debug( LDAP_DEBUG_TRACE, "*** got %ld of %lu so far\n",
136 (long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
137 conn->c_currentber->ber_len, 0 );
139 if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
140 /* log, close and send error */
141 ber_free( conn->c_currentber, 1 );
142 conn->c_currentber = NULL;
144 close_connection( conn, conn->c_connid, -1 );
149 ber = conn->c_currentber;
150 conn->c_currentber = NULL;
152 if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
153 /* log, close and send error */
154 Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0,
158 close_connection( conn, conn->c_connid, -1 );
162 if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
163 /* log, close and send error */
164 Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0,
168 close_connection( conn, conn->c_connid, -1 );
173 if ( conn->c_version == 30 ) {
174 (void) ber_skip_tag( ber, &len );
178 arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
181 pthread_mutex_lock( &conn->c_dnmutex );
182 if ( conn->c_dn != NULL ) {
183 tmpdn = ch_strdup( conn->c_dn );
187 pthread_mutex_unlock( &conn->c_dnmutex );
189 pthread_mutex_lock( &conn->c_opsmutex );
190 arg->co_op = slap_op_add( &conn->c_ops, ber, msgid, tag, tmpdn,
191 conn->c_opsinitiated, conn->c_connid );
192 pthread_mutex_unlock( &conn->c_opsmutex );
194 if ( tmpdn != NULL ) {
198 pthread_attr_init( &attr );
199 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
200 #if !defined(HAVE_PTHREADS_D4)
201 /* POSIX_THREADS or compatible
202 * This is a draft 10 or standard pthreads implementation
204 if ( pthread_create( &arg->co_op->o_tid, &attr,
205 connection_operation, (void *) arg ) != 0 ) {
206 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
208 pthread_mutex_lock( &active_threads_mutex );
210 pthread_mutex_unlock( &active_threads_mutex );
212 #else /* pthread draft4 */
214 * This is a draft 4 or earlier pthreads implementation
216 if ( pthread_create( &arg->co_op->o_tid, attr,
217 connection_operation, (void *) arg ) != 0 ) {
218 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
220 pthread_mutex_lock( &active_threads_mutex );
222 pthread_mutex_unlock( &active_threads_mutex );
224 #endif /* pthread draft4 */
225 pthread_attr_destroy( &attr );