mosty comment and documentation cleanup on waitevent.
authorLuigi Rizzo <rizzo@icir.org>
Tue, 28 Nov 2006 12:05:25 +0000 (12:05 +0000)
committerLuigi Rizzo <rizzo@icir.org>
Tue, 28 Nov 2006 12:05:25 +0000 (12:05 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@48082 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/manager.c

index d15cc72..6207bb2 100644 (file)
@@ -139,7 +139,7 @@ struct mansession {
        int fd;                 /*!< descriptor used for output. Either the socket (AMI) or a temporary file (HTTP) */
        int inuse;              /*!< number of HTTP sessions using this entry */
        int needdestroy;        /*!< Whether an HTTP session should be destroyed */
-       pthread_t waiting_thread;       /*!< Whether an HTTP session has someone waiting on events */
+       pthread_t waiting_thread;       /*!< Sleeping thread using this descriptor */
        unsigned long managerid;        /*!< Unique manager identifier, 0 for AMI sessions */
        time_t sessiontimeout;  /*!< Session timeout if HTTP */
        struct ast_dynamic_str *outputstr;      /*!< Output from manager interface */
@@ -1110,15 +1110,14 @@ static char mandescr_waitevent[] =
 "a manager event is queued.  Once WaitEvent has been called on an HTTP manager\n"
 "session, events will be generated and queued.\n"
 "Variables: \n"
-"   Timeout: Maximum time to wait for events\n";
+"   Timeout: Maximum time (in seconds) to wait for events, -1 means forever.\n";
 
 static int action_waitevent(struct mansession *s, struct message *m)
 {
        char *timeouts = astman_get_header(m, "Timeout");
-       int timeout = -1, max;
+       int timeout = -1;
        int x;
        int needexit = 0;
-       time_t now;
        char *id = astman_get_header(m,"ActionID");
        char idText[256] = "";
 
@@ -1127,31 +1126,46 @@ static int action_waitevent(struct mansession *s, struct message *m)
 
        if (!ast_strlen_zero(timeouts)) {
                sscanf(timeouts, "%i", &timeout);
+               if (timeout < -1)
+                       timeout = -1;
+               /* XXX maybe put an upper bound, or prevent the use of 0 ? */
        }
 
        ast_mutex_lock(&s->__lock);
-       if (s->waiting_thread != AST_PTHREADT_NULL) {
+       if (s->waiting_thread != AST_PTHREADT_NULL)
                pthread_kill(s->waiting_thread, SIGURG);
-       }
-       if (s->sessiontimeout) {
-               time(&now);
-               max = s->sessiontimeout - now - 10;
-               if (max < 0)
+
+       if (s->managerid) { /* AMI-over-HTTP session */
+               /*
+                * Make sure the timeout is within the expire time of the session,
+                * as the client will likely abort the request if it does not see
+                * data coming after some amount of time.
+                */
+               time_t now = time(NULL);
+               int max = s->sessiontimeout - now - 10;
+
+               if (max < 0)    /* We are already late. Strange but possible. */
                        max = 0;
-               if ((timeout < 0) || (timeout > max))
+               if (timeout < 0 || timeout > max)
                        timeout = max;
-               if (!s->send_events)
+               if (!s->send_events)    /* make sure we record events */
                        s->send_events = -1;
-               /* Once waitevent is called, always queue events from now on */
        }
        ast_mutex_unlock(&s->__lock);
-       s->waiting_thread = pthread_self();
+
+       /* XXX should this go inside the lock ? */
+       s->waiting_thread = pthread_self();     /* let new events wake up this thread */
        if (option_debug)
                ast_log(LOG_DEBUG, "Starting waiting for an event!\n");
-       for (x=0; ((x < timeout) || (timeout < 0)); x++) {
+
+       for (x=0; x < timeout || timeout < 0; x++) {
                ast_mutex_lock(&s->__lock);
                if (NEW_EVENT(s))
                        needexit = 1;
+               /* We can have multiple HTTP session point to the same mansession entry.
+                * The way we deal with it is not very nice: newcomers kick out the previous
+                * HTTP session. XXX this needs to be improved.
+                */
                if (s->waiting_thread != pthread_self())
                        needexit = 1;
                if (s->needdestroy)
@@ -1171,8 +1185,7 @@ static int action_waitevent(struct mansession *s, struct message *m)
        ast_mutex_lock(&s->__lock);
        if (s->waiting_thread == pthread_self()) {
                struct eventqent *eqe;
-               astman_send_response(s, m, "Success", "Waiting for Event...");
-               /* Only show events if we're the most recent waiter */
+               astman_send_response(s, m, "Success", "Waiting for Event completed.");
                while ( (eqe = NEW_EVENT(s)) ) {
                        ref_event(eqe);
                        if (((s->readperm & eqe->category) == eqe->category) &&