[asterisk-commits] rizzo: trunk r45597 - /trunk/main/manager.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Wed Oct 18 14:30:23 MST 2006


Author: rizzo
Date: Wed Oct 18 16:30:21 2006
New Revision: 45597

URL: http://svn.digium.com/view/asterisk?rev=45597&view=rev
Log:
+ move output_format variables in the http section of the file;
+ more comments on struct mansession and global variables;
+ small improvements to the session matching code so it supports
  multiple sessions from the same IP


Modified:
    trunk/main/manager.c

Modified: trunk/main/manager.c
URL: http://svn.digium.com/view/asterisk/trunk/main/manager.c?rev=45597&r1=45596&r2=45597&view=diff
==============================================================================
--- trunk/main/manager.c (original)
+++ trunk/main/manager.c Wed Oct 18 16:30:21 2006
@@ -83,26 +83,14 @@
 	char eventdata[1];	/* really variable size, allocated by append_event() */
 };
 
-enum output_format {
-	FORMAT_RAW,
-	FORMAT_HTML,
-	FORMAT_XML,
-};
-
-static char *contenttype[] = {
-	[FORMAT_RAW] = "plain",
-	[FORMAT_HTML] = "html",
-	[FORMAT_XML] =  "xml",
-};
-
 static int enabled = 0;
 static int portno = DEFAULT_MANAGER_PORT;
-static int asock = -1;
+static int asock = -1;	/* the accept socket */
 static int displayconnects = 1;
 static int timestampevents = 0;
 static int httptimeout = 60;
 
-static pthread_t t;
+static pthread_t accept_thread_ptr;	/* the accept thread */
 static int block_sockets = 0;
 static int num_sessions = 0;
 
@@ -121,17 +109,19 @@
 
 /*! \brief Descriptor for an AMI session, either a regular one
  * or one over http.
+ * For AMI sessions, the entry is created upon a connect, and destroyed
+ * with the socket.
  */
 struct mansession {
-	pthread_t t;		/*! Execution thread */
+	pthread_t ms_t;		/*! Execution thread, basically useless */
 	ast_mutex_t __lock;	/*! Thread lock -- don't use in action callbacks, it's already taken care of  */
 				/* XXX need to document which fields it is protecting */
-	struct sockaddr_in sin;	/*! socket address */
+	struct sockaddr_in sin;	/*! address we are connecting from */
 	int fd;			/*! descriptor used for output. Either the socket (AMI) or a temporary file (HTTP) */
-	int inuse;		/*! Whether an HTTP (XXX or AMI ?) manager is in use */
+	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 */
-	unsigned long managerid;	/*! Unique manager identifer */
+	unsigned long managerid;	/*! Unique manager identifer, 0 for AMI sessions */
 	time_t sessiontimeout;	/*! Session timeout if HTTP */
 	struct ast_dynamic_str *outputstr;	/*! Output from manager interface */
 	char username[80];	/*! Logged in username */
@@ -511,7 +501,7 @@
 static void unuse_eventqent(struct eventqent *e)
 {
 	if (ast_atomic_dec_and_test(&e->usecount) && e->next)
-		pthread_kill(t, SIGURG);
+		pthread_kill(accept_thread_ptr, SIGURG);
 }
 
 static void free_session(struct mansession *s)
@@ -532,6 +522,7 @@
 static void destroy_session(struct mansession *s)
 {
 	AST_LIST_LOCK(&sessions);
+	ast_verbose("destroy session %lx\n", s->managerid);
 	AST_LIST_REMOVE(&sessions, s, list);
 	AST_LIST_UNLOCK(&sessions);
 
@@ -1938,6 +1929,8 @@
 		AST_LIST_LOCK(&sessions);
 		AST_LIST_TRAVERSE_SAFE_BEGIN(&sessions, s, list) {
 			if (s->sessiontimeout && (now > s->sessiontimeout) && !s->inuse) {
+				ast_verbose("destroy session[2] %lx now %lu to %lu\n",
+					s->managerid, now, s->sessiontimeout);
 				AST_LIST_REMOVE_CURRENT(&sessions, list);
 				ast_atomic_fetchadd_int(&num_sessions, -1);
 				if (s->authenticated && (option_verbose > 1) && displayconnects) {
@@ -2010,7 +2003,7 @@
 			s->eventq = s->eventq->next;
 		AST_LIST_UNLOCK(&sessions);
 		ast_atomic_fetchadd_int(&s->eventq->usecount, 1);
-		if (ast_pthread_create_background(&s->t, &attr, session_do, s))
+		if (ast_pthread_create_background(&s->ms_t, &attr, session_do, s))
 			destroy_session(s);
 	}
 	pthread_attr_destroy(&attr);
@@ -2189,15 +2182,31 @@
  * then fed back to the client over the original socket.
  */
 
+enum output_format {
+	FORMAT_RAW,
+	FORMAT_HTML,
+	FORMAT_XML,
+};
+
+static char *contenttype[] = {
+	[FORMAT_RAW] = "plain",
+	[FORMAT_HTML] = "html",
+	[FORMAT_XML] =  "xml",
+};
+
+/* locate an http session in the list using the cookie as a key */
 static struct mansession *find_session(unsigned long ident)
 {
 	struct mansession *s;
+
+	if (ident == 0)
+		return NULL;
 
 	AST_LIST_LOCK(&sessions);
 	AST_LIST_TRAVERSE(&sessions, s, list) {
 		ast_mutex_lock(&s->__lock);
 		if (s->sessiontimeout && (s->managerid == ident) && !s->needdestroy) {
-			s->inuse++;
+			ast_atomic_fetchadd_int(&s->inuse, 1);
 			break;
 		}
 		ast_mutex_unlock(&s->__lock);
@@ -2408,25 +2417,26 @@
 	for (v = params; v; v = v->next) {
 		if (!strcasecmp(v->name, "mansession_id")) {
 			sscanf(v->value, "%lx", &ident);
-			ast_verbose("session is <%lx>\n", ident);
 			break;
 		}
 	}
-	
+
 	if (!(s = find_session(ident))) {
-		/* Create new session */
+		/* Create new session.
+		 * While it is not in the list we don't need any locking
+		 */
 		if (!(s = ast_calloc(1, sizeof(*s)))) {
 			*status = 500;
 			goto generic_callback_out;
 		}
-		memcpy(&s->sin, requestor, sizeof(s->sin));
+		s->sin = *requestor;
 		s->fd = -1;
 		s->waiting_thread = AST_PTHREADT_NULL;
 		s->send_events = 0;
 		ast_mutex_init(&s->__lock);
 		ast_mutex_lock(&s->__lock);
 		s->inuse = 1;
-		s->managerid = rand() | (unsigned long)s;
+		s->managerid = rand() | 1;	/* make sure it is non-zero */
 		AST_LIST_LOCK(&sessions);
 		AST_LIST_INSERT_HEAD(&sessions, s, list);
 		/* Hook into the last spot in the event queue */
@@ -2438,14 +2448,7 @@
 		ast_atomic_fetchadd_int(&num_sessions, 1);
 	}
 
-	/* Reset HTTP timeout.  If we're not yet authenticated, keep it extremely short */
-	time(&s->sessiontimeout);
-	if (!s->authenticated && (httptimeout > 5))
-		s->sessiontimeout += 5;
-	else
-		s->sessiontimeout += httptimeout;
 	ast_mutex_unlock(&s->__lock);
-	
 	memset(&m, 0, sizeof(m));
 	{
 		char tmp[80];
@@ -2542,6 +2545,10 @@
 		ast_build_string(&c, &len, "</table></body>\r\n");
 
 	ast_mutex_lock(&s->__lock);
+	/* Reset HTTP timeout.  If we're not authenticated, keep it extremely short */
+	s->sessiontimeout = time(NULL) + ((s->authenticated || httptimeout < 5) ? httptimeout : 5);
+	ast_verbose("die in %d seconds\n",
+		(int)(s->sessiontimeout - time(NULL)) );
 	if (s->needdestroy) {
 		if (s->inuse == 1) {
 			if (option_debug)
@@ -2831,7 +2838,7 @@
 		fcntl(asock, F_SETFL, flags | O_NONBLOCK);
 		if (option_verbose)
 			ast_verbose("Asterisk Management interface listening on port %d\n", portno);
-		ast_pthread_create_background(&t, NULL, accept_thread, NULL);
+		ast_pthread_create_background(&accept_thread_ptr, NULL, accept_thread, NULL);
 	}
 	return 0;
 }



More information about the asterisk-commits mailing list