mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-09 02:52:04 +08:00
Improved "closing" handling. Remove fd from read set when state
changes to closing. Need to add protection against read set races.
This commit is contained in:
parent
6553a1fc77
commit
f1e15ddfa2
@ -16,6 +16,18 @@ static Connection *connections = NULL;
|
||||
static int conn_index = -1;
|
||||
static long conn_nextid = 0;
|
||||
|
||||
/* structure state (protected by connections_mutex) */
|
||||
#define SLAP_C_UNINITIALIZED 0x0 /* MUST BE ZERO (0) */
|
||||
#define SLAP_C_UNUSED 0x1
|
||||
#define SLAP_C_USED 0x2
|
||||
|
||||
/* connection state (protected by c_mutex ) */
|
||||
#define SLAP_C_INVALID 0x0 /* MUST BE ZERO (0) */
|
||||
#define SLAP_C_INACTIVE 0x1 /* zero threads */
|
||||
#define SLAP_C_ACTIVE 0x2 /* one or more threads */
|
||||
#define SLAP_C_BINDING 0x3 /* binding */
|
||||
#define SLAP_C_CLOSING 0x4 /* closing */
|
||||
|
||||
static Connection* connection_get( int s );
|
||||
|
||||
static int connection_input( Connection *c );
|
||||
@ -288,6 +300,20 @@ connection_destroy( Connection *c )
|
||||
lber_pvt_sb_destroy( &c->c_sb );
|
||||
}
|
||||
|
||||
void connection_closing( Connection *c )
|
||||
{
|
||||
assert( connections != NULL );
|
||||
assert( c != NULL );
|
||||
assert( c->c_struct_state == SLAP_C_USED );
|
||||
assert( c->c_conn_state != SLAP_C_INVALID );
|
||||
|
||||
if( c->c_conn_state != SLAP_C_CLOSING ) {
|
||||
/* don't listen on this port anymore */
|
||||
slapd_clr_read( c->c_sb.sb_sd, 1 );
|
||||
c->c_conn_state = SLAP_C_CLOSING;
|
||||
}
|
||||
}
|
||||
|
||||
static void connection_close( Connection *c )
|
||||
{
|
||||
assert( connections != NULL );
|
||||
@ -483,7 +509,7 @@ connection_operation( void *arg_v )
|
||||
case LDAP_REQ_UNBIND_30:
|
||||
#endif
|
||||
case LDAP_REQ_UNBIND:
|
||||
conn->c_conn_state = SLAP_C_CLOSING;
|
||||
connection_closing( conn );
|
||||
break;
|
||||
|
||||
case LDAP_REQ_BIND:
|
||||
@ -550,7 +576,7 @@ int connection_read(int s)
|
||||
"connection_read(%d): input error id=%ld, closing.\n",
|
||||
s, c->c_connid, 0 );
|
||||
|
||||
c->c_conn_state = SLAP_C_CLOSING;
|
||||
connection_closing( c );
|
||||
connection_close( c );
|
||||
}
|
||||
|
||||
@ -583,7 +609,8 @@ connection_input(
|
||||
"ber_get_next on fd %d failed errno %d (%s)\n",
|
||||
lber_pvt_sb_get_desc(&conn->c_sb), errno,
|
||||
errno > -1 && errno < sys_nerr ? sys_errlist[errno] : "unknown" );
|
||||
Debug( LDAP_DEBUG_TRACE, "\t*** got %ld of %lu so far\n",
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"\t*** got %ld of %lu so far\n",
|
||||
(long)(conn->c_currentber->ber_rwptr - conn->c_currentber->ber_buf),
|
||||
conn->c_currentber->ber_len, 0 );
|
||||
|
||||
|
@ -58,9 +58,11 @@ static void slapd_add(int s) {
|
||||
assert( !FD_ISSET( s, &slap_daemon.sd_readers ));
|
||||
assert( !FD_ISSET( s, &slap_daemon.sd_writers ));
|
||||
|
||||
#ifndef HAVE_WINSOCK
|
||||
if (s >= slap_daemon.sd_nfds) {
|
||||
slap_daemon.sd_nfds = s + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
FD_SET( s, &slap_daemon.sd_actives );
|
||||
FD_SET( s, &slap_daemon.sd_readers );
|
||||
@ -78,7 +80,6 @@ static void slapd_add(int s) {
|
||||
void slapd_remove(int s) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( s < slap_daemon.sd_nfds );
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives ));
|
||||
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: removing %d%s%s\n", s,
|
||||
@ -95,10 +96,8 @@ void slapd_remove(int s) {
|
||||
void slapd_clr_write(int s, int wake) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( s < slap_daemon.sd_nfds );
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives) );
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_writers) );
|
||||
FD_SET( s, &slap_daemon.sd_writers );
|
||||
FD_CLR( s, &slap_daemon.sd_writers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
|
||||
@ -110,6 +109,7 @@ void slapd_clr_write(int s, int wake) {
|
||||
void slapd_set_write(int s, int wake) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives) );
|
||||
FD_SET( s, &slap_daemon.sd_writers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
@ -119,6 +119,32 @@ void slapd_set_write(int s, int wake) {
|
||||
}
|
||||
}
|
||||
|
||||
void slapd_clr_read(int s, int wake) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives) );
|
||||
FD_CLR( s, &slap_daemon.sd_readers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
|
||||
if( wake ) {
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
}
|
||||
}
|
||||
|
||||
void slapd_set_read(int s, int wake) {
|
||||
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
|
||||
|
||||
assert( FD_ISSET( s, &slap_daemon.sd_actives) );
|
||||
FD_SET( s, &slap_daemon.sd_readers );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
|
||||
|
||||
if( wake ) {
|
||||
ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 );
|
||||
}
|
||||
}
|
||||
|
||||
static void slapd_close(int s) {
|
||||
slapd_remove(s);
|
||||
|
||||
|
@ -115,6 +115,8 @@ long connection_init LDAP_P((
|
||||
int s,
|
||||
const char* name, const char* addr));
|
||||
|
||||
void connection_closing LDAP_P(( Connection *c ));
|
||||
|
||||
int connection_write LDAP_P((int s));
|
||||
int connection_read LDAP_P((int s));
|
||||
|
||||
@ -310,6 +312,11 @@ extern int slap_destroy LDAP_P((void));
|
||||
struct sockaddr_in;
|
||||
extern int slapd_daemon LDAP_P((struct sockaddr_in *addr));
|
||||
|
||||
extern void slapd_set_write LDAP_P((int s, int wake));
|
||||
extern void slapd_clr_write LDAP_P((int s, int wake));
|
||||
extern void slapd_set_read LDAP_P((int s, int wake));
|
||||
extern void slapd_clr_read LDAP_P((int s, int wake));
|
||||
|
||||
extern void slap_set_shutdown LDAP_P((int sig));
|
||||
extern void slap_do_nothing LDAP_P((int sig));
|
||||
|
||||
|
@ -104,7 +104,7 @@ send_ldap_result2(
|
||||
: "unknown", 0 );
|
||||
|
||||
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
|
||||
conn->c_conn_state = SLAP_C_CLOSING;
|
||||
connection_closing( conn );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
@ -334,7 +334,7 @@ send_search_entry(
|
||||
: "unknown", 0 );
|
||||
|
||||
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
|
||||
conn->c_conn_state = SLAP_C_CLOSING;
|
||||
connection_closing( conn );
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
|
||||
|
@ -414,19 +414,6 @@ typedef struct slap_op {
|
||||
* represents a connection from an ldap client
|
||||
*/
|
||||
|
||||
|
||||
/* structure state (protected by connections_mutex) */
|
||||
#define SLAP_C_UNINITIALIZED 0x0 /* MUST BE ZERO (0) */
|
||||
#define SLAP_C_UNUSED 0x1
|
||||
#define SLAP_C_USED 0x2
|
||||
|
||||
/* connection state (protected by c_mutex ) */
|
||||
#define SLAP_C_INVALID 0x0 /* MUST BE ZERO (0) */
|
||||
#define SLAP_C_INACTIVE 0x1 /* zero threads */
|
||||
#define SLAP_C_ACTIVE 0x2 /* one or more threads */
|
||||
#define SLAP_C_BINDING 0x3 /* binding */
|
||||
#define SLAP_C_CLOSING 0x4 /* closing */
|
||||
|
||||
typedef struct slap_conn {
|
||||
int c_struct_state; /* structure management state */
|
||||
int c_conn_state; /* connection state */
|
||||
|
Loading…
Reference in New Issue
Block a user