comment and cleanup the main thread.

On passing, fix a bug: close the socket if the allocation
of a structure for the new session fails.
(the bugfix is a candidate for 1.4)



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@45561 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Luigi Rizzo 19 years ago
parent eb3767cafe
commit 71cf14207c

@ -2046,29 +2046,32 @@ static void *session_do(void *data)
return NULL; return NULL;
} }
/*! \brief The thread accepting connections on the manager interface port.
* As a side effect, it purges stale sessions, one per each iteration,
* which is at least every 5 seconds.
*/
static void *accept_thread(void *ignore) static void *accept_thread(void *ignore)
{ {
int as;
struct sockaddr_in sin;
socklen_t sinlen;
struct eventqent *eqe;
struct mansession *s;
struct protoent *p;
int arg = 1;
int flags;
pthread_attr_t attr; pthread_attr_t attr;
time_t now;
struct pollfd pfds[1];
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for (;;) { for (;;) {
time(&now); struct mansession *s;
time_t now = time(NULL);
int as;
struct sockaddr_in sin;
socklen_t sinlen;
struct protoent *p;
int flags;
struct pollfd pfds[1];
AST_LIST_LOCK(&sessions); AST_LIST_LOCK(&sessions);
AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) { AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) {
if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) { if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) {
AST_LIST_REMOVE_CURRENT(&sessions, list); AST_LIST_REMOVE_CURRENT(&sessions, list);
ast_atomic_fetchadd_int(&num_sessions, -1);
if (s->authenticated && (option_verbose > 1) && displayconnects) { if (s->authenticated && (option_verbose > 1) && displayconnects) {
ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n", ast_verbose(VERBOSE_PREFIX_2 "HTTP Manager '%s' timed out from %s\n",
s->username, ast_inet_ntoa(s->sin.sin_addr)); s->username, ast_inet_ntoa(s->sin.sin_addr));
@ -2082,13 +2085,11 @@ static void *accept_thread(void *ignore)
always keep at least one in the queue */ always keep at least one in the queue */
/* XXX why do we need one entry in the queue ? */ /* XXX why do we need one entry in the queue ? */
while (master_eventq->next && !master_eventq->usecount) { while (master_eventq->next && !master_eventq->usecount) {
eqe = master_eventq; struct eventqent *eqe = master_eventq;
master_eventq = master_eventq->next; master_eventq = master_eventq->next;
free(eqe); free(eqe);
} }
AST_LIST_UNLOCK(&sessions); AST_LIST_UNLOCK(&sessions);
if (s)
ast_atomic_fetchadd_int(&num_sessions, -1);
sinlen = sizeof(sin); sinlen = sizeof(sin);
pfds[0].fd = asock; pfds[0].fd = asock;
@ -2104,30 +2105,34 @@ static void *accept_thread(void *ignore)
} }
p = getprotobyname("tcp"); p = getprotobyname("tcp");
if (p) { if (p) {
int arg = 1;
if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) { if( setsockopt(as, p->p_proto, TCP_NODELAY, (char *)&arg, sizeof(arg) ) < 0 ) {
ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno)); ast_log(LOG_WARNING, "Failed to set manager tcp connection to TCP_NODELAY mode: %s\n", strerror(errno));
} }
} }
if (!(s = ast_calloc(1, sizeof(*s)))) s = ast_calloc(1, sizeof(*s)); /* allocate a new record */
if (!s) {
close(as);
continue; continue;
}
ast_atomic_fetchadd_int(&num_sessions, 1);
s->sin = sin;
memcpy(&s->sin, &sin, sizeof(sin));
s->writetimeout = 100; s->writetimeout = 100;
s->waiting_thread = AST_PTHREADT_NULL; s->waiting_thread = AST_PTHREADT_NULL;
if (!block_sockets) { flags = fcntl(as, F_GETFL);
/* For safety, make sure socket is non-blocking */ if (!block_sockets) /* For safety, make sure socket is non-blocking */
flags = fcntl(as, F_GETFL); flags |= O_NONBLOCK;
fcntl(as, F_SETFL, flags | O_NONBLOCK); else
} else { flags &= ~O_NONBLOCK;
flags = fcntl(as, F_GETFL); fcntl(as, F_SETFL, flags);
fcntl(as, F_SETFL, flags & ~O_NONBLOCK);
}
ast_mutex_init(&s->__lock); ast_mutex_init(&s->__lock);
s->fd = as; s->fd = as;
s->send_events = -1; s->send_events = -1;
ast_atomic_fetchadd_int(&num_sessions, 1);
AST_LIST_LOCK(&sessions); AST_LIST_LOCK(&sessions);
AST_LIST_INSERT_HEAD(&sessions, s, list); AST_LIST_INSERT_HEAD(&sessions, s, list);
/* Find the last place in the master event queue and hook ourselves /* Find the last place in the master event queue and hook ourselves

Loading…
Cancel
Save