8 #include <sys/socket.h>
13 extern Operation *op_add();
14 extern int active_threads;
15 extern pthread_mutex_t active_threads_mutex;
16 extern pthread_mutex_t new_conn_mutex;
17 extern long ops_initiated;
18 extern long ops_completed;
19 extern pthread_mutex_t ops_mutex;
20 extern pthread_t listener_tid;
22 #ifndef DECL_SYS_ERRLIST
24 extern char *sys_errlist[];
33 * connection_activity - handle the request operation op on connection
34 * conn. This routine figures out what kind of operation it is and
35 * calls the appropriate stub to handle it.
39 connection_operation( struct co_arg *arg )
43 pthread_mutex_lock( &arg->co_conn->c_opsmutex );
44 arg->co_conn->c_opsinitiated++;
45 pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
47 pthread_mutex_lock( &ops_mutex );
49 pthread_mutex_unlock( &ops_mutex );
51 switch ( arg->co_op->o_tag ) {
53 do_bind( arg->co_conn, arg->co_op );
57 case LDAP_REQ_UNBIND_30:
60 do_unbind( arg->co_conn, arg->co_op );
64 do_add( arg->co_conn, arg->co_op );
68 case LDAP_REQ_DELETE_30:
71 do_delete( arg->co_conn, arg->co_op );
75 do_modrdn( arg->co_conn, arg->co_op );
79 do_modify( arg->co_conn, arg->co_op );
82 case LDAP_REQ_COMPARE:
83 do_compare( arg->co_conn, arg->co_op );
87 do_search( arg->co_conn, arg->co_op );
91 case LDAP_REQ_ABANDON_30:
93 case LDAP_REQ_ABANDON:
94 do_abandon( arg->co_conn, arg->co_op );
98 Debug( LDAP_DEBUG_ANY, "unknown request 0x%x\n",
99 arg->co_op->o_tag, 0, 0 );
103 pthread_mutex_lock( &arg->co_conn->c_opsmutex );
104 arg->co_conn->c_opscompleted++;
105 op_delete( &arg->co_conn->c_ops, arg->co_op );
106 pthread_mutex_unlock( &arg->co_conn->c_opsmutex );
108 free( (char *) arg );
110 pthread_mutex_lock( &ops_mutex );
112 pthread_mutex_unlock( &ops_mutex );
114 pthread_mutex_lock( &active_threads_mutex );
116 pthread_mutex_unlock( &active_threads_mutex );
126 unsigned long tag, len;
131 if ( conn->c_currentber == NULL && (conn->c_currentber = ber_alloc())
133 Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
138 if ( (tag = ber_get_next( &conn->c_sb, &len, conn->c_currentber ))
139 != LDAP_TAG_MESSAGE ) {
140 Debug( LDAP_DEBUG_TRACE,
141 "ber_get_next on fd %d failed errno %d (%s)\n",
142 conn->c_sb.sb_sd, errno, errno > -1 && errno < sys_nerr ?
143 sys_errlist[errno] : "unknown" );
144 Debug( LDAP_DEBUG_TRACE, "*** got %d of %d so far\n",
145 conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf,
146 conn->c_currentber->ber_len, 0 );
148 if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
149 /* log, close and send error */
150 ber_free( conn->c_currentber, 1 );
151 conn->c_currentber = NULL;
153 close_connection( conn, conn->c_connid, -1 );
158 ber = conn->c_currentber;
159 conn->c_currentber = NULL;
161 if ( (tag = ber_get_int( ber, &msgid )) != LDAP_TAG_MSGID ) {
162 /* log, close and send error */
163 Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%x\n", tag, 0,
167 close_connection( conn, conn->c_connid, -1 );
171 if ( (tag = ber_peek_tag( ber, &len )) == LBER_ERROR ) {
172 /* log, close and send error */
173 Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%x\n", tag, 0,
177 close_connection( conn, conn->c_connid, -1 );
182 if ( conn->c_version == 30 ) {
183 (void) ber_skip_tag( ber, &len );
187 arg = (struct co_arg *) ch_malloc( sizeof(struct co_arg) );
190 pthread_mutex_lock( &conn->c_dnmutex );
191 if ( conn->c_dn != NULL ) {
192 tmpdn = strdup( conn->c_dn );
196 pthread_mutex_unlock( &conn->c_dnmutex );
198 pthread_mutex_lock( &conn->c_opsmutex );
199 arg->co_op = op_add( &conn->c_ops, ber, msgid, tag, tmpdn,
200 conn->c_opsinitiated, conn->c_connid );
201 pthread_mutex_unlock( &conn->c_opsmutex );
203 if ( tmpdn != NULL ) {
207 pthread_attr_init( &attr );
208 pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
209 #ifndef THREAD_MIT_PTHREADS
210 /* POSIX_THREADS or compatible
211 * This is a draft 10 or standard pthreads implementation
213 if ( pthread_create( &arg->co_op->o_tid, &attr,
214 (void *) connection_operation, (void *) arg ) != 0 ) {
215 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
217 pthread_mutex_lock( &active_threads_mutex );
219 pthread_mutex_unlock( &active_threads_mutex );
221 #else /* !THREAD_MIT_PTHREAD */
223 * This is a draft 4 or earlier pthreads implementation
225 if ( pthread_create( &arg->co_op->o_tid, attr,
226 (void *) connection_operation, (void *) arg ) != 0 ) {
227 Debug( LDAP_DEBUG_ANY, "pthread_create failed\n", 0, 0, 0 );
229 pthread_mutex_lock( &active_threads_mutex );
231 pthread_mutex_unlock( &active_threads_mutex );
233 #endif /* !THREAD_MIT_PTHREAD */
234 pthread_attr_destroy( &attr );