[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