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;
29 ldap_pvt_thread_mutex_lock( &arg->co_conn->c_opsmutex );
30 arg->co_conn->c_opsinitiated++;
31 ldap_pvt_thread_mutex_unlock( &arg->co_conn->c_opsmutex );
33 ldap_pvt_thread_mutex_lock( &ops_mutex );
35 ldap_pvt_thread_mutex_unlock( &ops_mutex );
37 switch ( arg->co_op->o_tag ) {
39 do_bind( arg->co_conn, arg->co_op );
43 case LDAP_REQ_UNBIND_30:
46 do_unbind( arg->co_conn, arg->co_op );
50 do_add( arg->co_conn, arg->co_op );
54 case LDAP_REQ_DELETE_30:
57 do_delete( arg->co_conn, arg->co_op );
61 do_modrdn( arg->co_conn, arg->co_op );
65 do_modify( arg->co_conn, arg->co_op );
68 case LDAP_REQ_COMPARE:
69 do_compare( arg->co_conn, arg->co_op );
73 do_search( arg->co_conn, arg->co_op );
77 case LDAP_REQ_ABANDON_30:
79 case LDAP_REQ_ABANDON:
80 do_abandon( arg->co_conn, arg->co_op );
84 Debug( LDAP_DEBUG_ANY, "unknown request 0x%lx\n",
85 arg->co_op->o_tag, 0, 0 );
89 ldap_pvt_thread_mutex_lock( &arg->co_conn->c_opsmutex );
90 arg->co_conn->c_opscompleted++;
92 slap_op_delete( &arg->co_conn->c_ops, arg->co_op );
95 ldap_pvt_thread_mutex_unlock( &arg->co_conn->c_opsmutex );
100 ldap_pvt_thread_mutex_lock( &ops_mutex );
102 ldap_pvt_thread_mutex_unlock( &ops_mutex );
104 ldap_pvt_thread_mutex_lock( &active_threads_mutex );
106 if( active_threads < 1 ) {
107 ldap_pvt_thread_cond_signal(&active_threads_cond);
109 ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
120 unsigned long tag, len;
125 if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
127 Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
132 if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
133 != LDAP_TAG_MESSAGE ) {
134 Debug( LDAP_DEBUG_TRACE,
135 "ber_get_next on fd %d failed errno %d (%s)\n",
136 conn->c_sb.sb_sd, errno, errno > -1 && errno < sys_nerr ?
137 sys_errlist[errno] : "unknown" );
138 Debug( LDAP_DEBUG_TRACE, "*** got %ld of %lu so far\n",
139 (long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
140 conn->c_currentber->ber_len, 0 );
142 if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
143 /* log, close and send error */
144 ber_free( conn->c_currentber, 1 );
145 conn->c_currentber = NULL;
147 close_connection( conn, conn->c_connid, -1 );
152 ber = conn->c_currentber;
153 conn->c_currentber = NULL;
155 if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
156 /* log, close and send error */
157 Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0,
161 close_connection( conn, conn->c_connid, -1 );
165 if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
166 /* log, close and send error */
167 Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0,
171 close_connection( conn, conn->c_connid, -1 );
176 if ( conn->c_version == 30 ) {
177 (void) ber_skip_tag( ber, &len );
181 arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
184 ldap_pvt_thread_mutex_lock( &conn->c_dnmutex );
185 if ( conn->c_dn != NULL ) {
186 tmpdn = ch_strdup( conn->c_dn );
190 ldap_pvt_thread_mutex_unlock( &conn->c_dnmutex );
192 ldap_pvt_thread_mutex_lock( &conn->c_opsmutex );
193 arg->co_op = slap_op_add( &conn->c_ops, ber, msgid, tag, tmpdn,
194 conn->c_opsinitiated, conn->c_connid );
195 ldap_pvt_thread_mutex_unlock( &conn->c_opsmutex );
197 if ( tmpdn != NULL ) {
201 ldap_pvt_thread_mutex_lock( &active_threads_mutex );
203 ldap_pvt_thread_mutex_unlock( &active_threads_mutex );
205 if ( status = ldap_pvt_thread_create( &arg->co_op->o_tid, 1,
206 connection_operation, (void *) arg ) != 0 ) {
207 Debug( LDAP_DEBUG_ANY, "ldap_pvt_thread_create failed (%d)\n", status, 0, 0 );