[Freeswitch-svn] [commit] r12605 - in freeswitch/trunk/libs/esl: . src src/include

FreeSWITCH SVN anthm at freeswitch.org
Sat Mar 14 12:23:08 PDT 2009


Author: anthm
Date: Sat Mar 14 14:23:07 2009
New Revision: 12605

Log:
fix socket race

Modified:
   freeswitch/trunk/libs/esl/fs_cli.c
   freeswitch/trunk/libs/esl/src/esl.c
   freeswitch/trunk/libs/esl/src/esl_event.c
   freeswitch/trunk/libs/esl/src/esl_oop.cpp
   freeswitch/trunk/libs/esl/src/include/esl.h

Modified: freeswitch/trunk/libs/esl/fs_cli.c
==============================================================================
--- freeswitch/trunk/libs/esl/fs_cli.c	(original)
+++ freeswitch/trunk/libs/esl/fs_cli.c	Sat Mar 14 14:23:07 2009
@@ -193,8 +193,7 @@
 	thread_running = 1;
 
 	while(thread_running && handle->connected) {
-		esl_status_t status = esl_recv_timed(handle, 10);
-		
+		esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL);
 		if (status == ESL_FAIL) {
 			esl_log(ESL_LOG_WARNING, "Disconnected.\n");
 			running = thread_running = 0;
@@ -240,7 +239,11 @@
 				}
 				
 				if (!known) {
-					printf("INCOMING DATA [%s]\n%s", type, handle->last_event->body);
+					printf("INCOMING DATA [%s]\n%s\n", type, handle->last_event->body ? handle->last_event->body : "");
+						char *foo;
+						esl_event_serialize(handle->last_event, &foo, ESL_FALSE);
+						printf("RECV EVENT\n%s\n", foo);
+						free(foo);
 				}
 			}
 		}
@@ -724,6 +727,7 @@
 	print_banner(stdout);
 
 	esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n");
+	printf("%s\n", handle.last_sr_reply);
 
 	while (running) {
 

Modified: freeswitch/trunk/libs/esl/src/esl.c
==============================================================================
--- freeswitch/trunk/libs/esl/src/esl.c	(original)
+++ freeswitch/trunk/libs/esl/src/esl.c	Sat Mar 14 14:23:07 2009
@@ -683,6 +683,7 @@
 		esl_mutex_lock(mutex);
 	}
 
+	esl_event_safe_destroy(&handle->race_event);
 	esl_event_safe_destroy(&handle->last_event);
 	esl_event_safe_destroy(&handle->last_sr_event);
 	esl_event_safe_destroy(&handle->last_ievent);
@@ -705,20 +706,29 @@
 	return status;
 }
 
-ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms, esl_event_t **save_event)
+ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms, int check_q, esl_event_t **save_event)
 {
 	fd_set rfds, efds;
 	struct timeval tv = { 0 };
 	int max, activity;
 	esl_status_t status = ESL_SUCCESS;
 
+	if (check_q) {
+		esl_mutex_lock(handle->mutex);
+		if (handle->race_event) {
+			esl_mutex_unlock(handle->mutex);
+			return esl_recv_event(handle, check_q, save_event);
+		}
+		esl_mutex_unlock(handle->mutex);
+	}
+
 	if (!handle || !handle->connected || handle->sock == -1) {
 		return ESL_FAIL;
 	}
 
 	tv.tv_usec = ms * 1000;
 
-	esl_mutex_lock(handle->mutex);
+
 	FD_ZERO(&rfds);
 	FD_ZERO(&efds);
 
@@ -736,21 +746,21 @@
 	max = handle->sock + 1;
 	
 	if ((activity = select(max, &rfds, NULL, &efds, &tv)) < 0) {
-		status = ESL_FAIL;
-		goto done;
+		return ESL_FAIL;
+	}
+
+	if (esl_mutex_trylock(handle->mutex) != ESL_SUCCESS) {
+		return ESL_BREAK;
 	}
 
 	if (activity && FD_ISSET(handle->sock, &rfds)) {
-		if (esl_recv_event(handle, save_event)) {
+		if (esl_recv_event(handle, check_q, save_event)) {
 			status = ESL_FAIL;
-			goto done;
 		}
 	} else {
 		status = ESL_BREAK;
 	}
 
- done:
-
 	if (handle->mutex) esl_mutex_unlock(handle->mutex);
 
 	return status;
@@ -758,26 +768,41 @@
 }
 
 
-ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, esl_event_t **save_event)
+ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
 {
 	char *c;
 	esl_ssize_t rrval;
 	int crc = 0;
-	esl_event_t *revent = NULL;
+	esl_event_t *revent = NULL, *qevent = NULL;
 	char *beg;
 	char *hname, *hval;
 	char *col;
 	char *cl;
 	esl_ssize_t len;
 	int zc = 0;
-	
 
 	if (!handle->connected) {
 		return ESL_FAIL;
 	}
-
+	
 	esl_mutex_lock(handle->mutex);
 
+	if (check_q && handle->race_event) {
+		qevent = handle->race_event;
+		handle->race_event = handle->race_event->next;
+		qevent->next = NULL;
+
+		if (save_event) {
+			*save_event = qevent;
+			qevent = NULL;
+		} else {
+			handle->last_event = qevent;
+		}
+		
+		esl_mutex_unlock(handle->mutex);
+		return ESL_SUCCESS;
+	}
+
 	esl_event_safe_destroy(&handle->last_event);
 	memset(handle->header_buf, 0, sizeof(handle->header_buf));
 
@@ -834,7 +859,7 @@
 			c++;
 		}
 	}
-
+	
 	if (!revent) {
 		goto fail;
 	}
@@ -862,6 +887,7 @@
 
 	if (save_event) {
 		*save_event = revent;
+		revent = NULL;
 	} else {
 		handle->last_event = revent;
 	}
@@ -992,19 +1018,50 @@
 		return ESL_FAIL;
 	}
 
+
 	esl_mutex_lock(handle->mutex);
 
+	esl_event_safe_destroy(&handle->last_event);
+	esl_event_safe_destroy(&handle->last_sr_event);
+
+	*handle->last_sr_reply = '\0';
+
 	if ((status = esl_send(handle, cmd))) {
+		esl_mutex_unlock(handle->mutex);
 		return status;
 	}
 
-	status = esl_recv_event(handle, &handle->last_sr_event);
-	
+ recv:	
+
+	status = esl_recv_event(handle, 0, &handle->last_sr_event);
+
 	if (handle->last_sr_event) {
-		hval = esl_event_get_header(handle->last_sr_event, "reply-text");
+		char *ct = esl_event_get_header(handle->last_sr_event,"content-type");
 
-		if (!esl_strlen_zero(hval)) {
-			strncpy(handle->last_sr_reply, hval, sizeof(handle->last_sr_reply));
+		if (strcasecmp(ct, "api/response") && strcasecmp(ct, "command/reply")) {
+			esl_event_t *ep;
+
+			for(ep = handle->race_event; ep && ep->next; ep = ep->next);
+			
+			if (ep) {
+				ep->next = handle->last_sr_event;
+			} else {
+				handle->race_event = handle->last_sr_event;
+			}
+
+			handle->last_sr_event = NULL;
+			
+			esl_mutex_unlock(handle->mutex);
+			esl_mutex_lock(handle->mutex);
+			goto recv;
+		}
+
+		if (handle->last_sr_event) {
+			hval = esl_event_get_header(handle->last_sr_event, "reply-text");
+
+			if (!esl_strlen_zero(hval)) {
+				strncpy(handle->last_sr_reply, hval, sizeof(handle->last_sr_reply));
+			}		
 		}
 	}
 	

Modified: freeswitch/trunk/libs/esl/src/esl_event.c
==============================================================================
--- freeswitch/trunk/libs/esl/src/esl_event.c	(original)
+++ freeswitch/trunk/libs/esl/src/esl_event.c	Sat Mar 14 14:23:07 2009
@@ -367,22 +367,25 @@
 
 ESL_DECLARE(void) esl_event_destroy(esl_event_t **event)
 {
-	esl_event_t *ep = *event;
-	esl_event_header_t *hp, *this;
+	esl_event_t *ep = *event, *this_event;
+	esl_event_header_t *hp, *this_header;
 
-	if (ep) {
-		for (hp = ep->headers; hp;) {
-			this = hp;
+	for (ep = *event ; ep ;) {
+		this_event = ep;
+		ep = ep->next;
+		
+		for (hp = this_event->headers; hp;) {
+			this_header = hp;
 			hp = hp->next;
-			FREE(this->name);
-			FREE(this->value);
-			memset(this, 0, sizeof(*this));
-			FREE(this);
-		}
-		FREE(ep->body);
-		FREE(ep->subclass_name);
-		memset(ep, 0, sizeof(*ep));
-		FREE(ep);
+			FREE(this_header->name);
+			FREE(this_header->value);
+			memset(this_header, 0, sizeof(*this_header));
+			FREE(this_header);
+		}
+		FREE(this_event->body);
+		FREE(this_event->subclass_name);
+		memset(this_event, 0, sizeof(*this_event));
+		FREE(this_event);
 	}
 	*event = NULL;
 }

Modified: freeswitch/trunk/libs/esl/src/esl_oop.cpp
==============================================================================
--- freeswitch/trunk/libs/esl/src/esl_oop.cpp	(original)
+++ freeswitch/trunk/libs/esl/src/esl_oop.cpp	Sat Mar 14 14:23:07 2009
@@ -154,7 +154,7 @@
 		delete last_event_obj;
 	}
 	
-	if (esl_recv_event(&handle, NULL) == ESL_SUCCESS) {
+	if (esl_recv_event(&handle, 1, NULL) == ESL_SUCCESS) {
 		esl_event_t *e = handle.last_ievent ? handle.last_ievent : handle.last_event;
 		if (e) {
 			esl_event_t *event;
@@ -176,7 +176,7 @@
 		last_event_obj = NULL;
 	}
 
-	if (esl_recv_event_timed(&handle, ms, NULL) == ESL_SUCCESS) {
+	if (esl_recv_event_timed(&handle, ms, 1, NULL) == ESL_SUCCESS) {
 		esl_event_t *e = handle.last_ievent ? handle.last_ievent : handle.last_event;
 		if (e) {
 			esl_event_t *event;

Modified: freeswitch/trunk/libs/esl/src/include/esl.h
==============================================================================
--- freeswitch/trunk/libs/esl/src/include/esl.h	(original)
+++ freeswitch/trunk/libs/esl/src/include/esl.h	Sat Mar 14 14:23:07 2009
@@ -266,6 +266,7 @@
 	char last_sr_reply[1024];
 	esl_event_t *last_event;
 	esl_event_t *last_sr_event;
+	esl_event_t *race_event;
 	esl_event_t *last_ievent;
 	esl_event_t *info_event;
 	int connected;
@@ -334,14 +335,14 @@
 ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, esl_port_t port, const char *password);
 ESL_DECLARE(esl_status_t) esl_disconnect(esl_handle_t *handle);
 ESL_DECLARE(esl_status_t) esl_send(esl_handle_t *handle, const char *cmd);
-ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, esl_event_t **save_event);
-ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms, esl_event_t **save_event);
+ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event);
+ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms, int check_q, esl_event_t **save_event);
 ESL_DECLARE(esl_status_t) esl_send_recv(esl_handle_t *handle, const char *cmd);
 ESL_DECLARE(esl_status_t) esl_filter(esl_handle_t *handle, const char *header, const char *value);
 ESL_DECLARE(esl_status_t) esl_events(esl_handle_t *handle, esl_event_type_t etype, const char *value);
 
-#define esl_recv(_h) esl_recv_event(_h, NULL)
-#define esl_recv_timed(_h, _ms) esl_recv_event_timed(_h, _ms, NULL)
+#define esl_recv(_h) esl_recv_event(_h, 0, NULL)
+#define esl_recv_timed(_h, _ms) esl_recv_event_timed(_h, _ms, 0, NULL)
 
 static __inline__ int esl_safe_strcasecmp(const char *s1, const char *s2)
 {



More information about the Freeswitch-svn mailing list