5 #include <sys/socket.h>
11 extern Operation *op_add();
12 extern int active_threads;
13 extern pthread_mutex_t active_threads_mutex;
14 extern pthread_mutex_t new_conn_mutex;
15 extern long ops_initiated;
16 extern long ops_completed;
17 extern pthread_mutex_t ops_mutex;
18 extern pthread_t listener_tid;
19 #ifndef SYSERRLIST_IN_STDIO
21 extern char *sys_errlist[];
30 * connection_activity - handle the request operation op on connection
31 * conn. This routine figures out what kind of operation it is and
32 * calls the appropriate stub to handle it.
36 connection_operation( struct co_arg *arg )
40 pthread_mutex_lock( &arg->co_conn->c_opsmutex );
41 arg->co_conn->c_opsinitiated++;
42 pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
44 pthread_mutex_lock( &ops_mutex );
46 pthread_mutex_unlock( &ops_mutex );
48 switch ( arg->co_op->o_tag ) {
50 do_bind( arg->co_conn, arg->co_op );
54 case LDAP_REQ_UNBIND_30:
57 do_unbind( arg->co_conn, arg->co_op );
61 do_add( arg->co_conn, arg->co_op );
65 case LDAP_REQ_DELETE_30:
68 do_delete( arg->co_conn, arg->co_op );
72 do_modrdn( arg->co_conn, arg->co_op );
76 do_modify( arg->co_conn, arg->co_op );
79 case LDAP_REQ_COMPARE:
80 do_compare( arg->co_conn, arg->co_op );
84 do_search( arg->co_conn, arg->co_op );
88 case LDAP_REQ_ABANDON_30:
90 case LDAP_REQ_ABANDON:
91 do_abandon( arg->co_conn, arg->co_op );
95 Debug( LDAP_DEBUG_ANY, "unknown request 0x%x\n",
96 arg->co_op->o_tag, 0, 0 );
100 pthread_mutex_lock( &arg->co_conn->c_opsmutex );
101 arg->co_conn->c_opscompleted++;
102 op_delete( &arg->co_conn->c_ops, arg->co_op );
103 pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
105 free( (char *) arg );
107 pthread_mutex_lock( &ops_mutex );
109 pthread_mutex_unlock( &ops_mutex );
111 pthread_mutex_lock( &active_threads_mutex );
113 pthread_mutex_unlock( &active_threads_mutex );
123 unsigned long tag, len;
128 if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
130 Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
135 if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
136 != LDAP_TAG_MESSAGE ) {
137 Debug( LDAP_DEBUG_TRACE,
138 "ber_get_next on fd %d failed errno %d (%s)\n",
139 conn->c_sb.sb_sd, errno, errno > -1 && errno < sys_nerr ?
140 sys_errlist[errno] : "unknown" );
141 Debug( LDAP_DEBUG_TRACE, "*** got %d of %d so far\n",
142 conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf,
143 conn->c_currentber->ber_len, 0 );
145 if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
146 /* log, close and send error */
147 ber_free( conn->c_currentber, 1 );
148 conn->c_currentber = NULL;
150 close_connection( conn, conn->c_connid, -1 );
155 ber = conn->c_currentber;
156 conn->c_currentber = NULL;
158 if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
159 /* log, close and send error */
160 Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%x\n", tag, 0,
164 close_connection( conn, conn->c_connid, -1 );
168 if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
169 /* log, close and send error */
170 Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%x\n", tag, 0,
174 close_connection( conn, conn->c_connid, -1 );
179 if ( conn->c_version == 30 ) {
180 (void) ber_skip_tag( ber, &len );
184 arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
187 pthread_mutex_lock( &conn->c_dnmutex );
188 if ( conn->c_dn != NULL ) {
189 tmpdn = strdup( conn->c_dn );
193 pthread_mutex_unlock( &conn->c_dnmutex );
195 pthread_mutex_lock( &conn->c_opsmutex );
196 arg->co_op = op_add( &conn->c_ops, ber, msgid, tag, tmpdn,
197 conn->c_opsinitiated, conn->c_connid );
198 pthread_mutex_unlock( &conn->c_opsmutex );
200 if ( tmpdn != NULL ) {
204 pthread_attr_init( &attr );
205 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
206 if ( pthread_create( &arg->co_op->o_tid, attr,
207 (void *) connection_operation, (void *) arg ) != 0 ) {
208 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
210 pthread_mutex_lock( &active_threads_mutex );
212 pthread_mutex_unlock( &active_threads_mutex );
214 pthread_attr_destroy( &attr );