esl_send_recv(handle, "connect\n\n");
-
if (handle->last_sr_event) {
handle->info_event = handle->last_sr_event;
handle->last_sr_event = NULL;
return ESL_SUCCESS;
}
- handle->connected = 0;
-
+ esl_disconnect(handle);
+
return ESL_FAIL;
}
}
-ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback)
+static int prepare_sock(esl_socket_t sock)
+{
+ int r = 0;
+
+#ifdef WIN32
+ u_long arg = 1;
+ if (ioctlsocket(sock, FIONBIO, &arg) == SOCKET_ERROR) {
+ r = -1;
+ }
+#else
+ int fd_flags = fcntl(sock, F_GETFL, 0);
+ if (fcntl(sock, F_SETFL, fd_flags | O_NONBLOCK)) {
+ r = -1;
+ }
+#endif
+
+}
+
+
+ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_listen_callback_t callback, esl_socket_t *server_sockP)
{
esl_socket_t server_sock = ESL_SOCK_INVALID;
struct sockaddr_in addr;
esl_status_t status = ESL_SUCCESS;
+
if ((server_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
return ESL_FAIL;
}
+ if (server_sockP) {
+ *server_sockP = server_sock;
+ }
+
+
esl_socket_reuseaddr(server_sock);
memset(&addr, 0, sizeof(addr));
status = ESL_FAIL;
goto end;
}
-
+ prepare_sock(client_sock);
callback(server_sock, client_sock, &echoClntAddr);
}
goto end;
}
+ prepare_sock(client_sock);
+
handler = malloc(sizeof(*handler));
esl_assert(handler);
handler->server_sock = server_sock;
handler->client_sock = client_sock;
handler->addr = echoClntAddr;
-
esl_thread_create_detached(client_thread, handler);
}
return ESL_SUCCESS;
fail:
-
+
handle->connected = 0;
esl_disconnect(handle);
{
esl_mutex_t *mutex = handle->mutex;
esl_status_t status = ESL_FAIL;
-
+ esl_event_t *ep;
+
if (handle->destroyed) {
return ESL_FAIL;
}
esl_mutex_lock(mutex);
}
- handle->destroyed = 1;
+
handle->connected = 0;
- esl_event_safe_destroy(&handle->race_event);
+ ep = handle->race_event;
+
+ while(ep) {
+ esl_event_t *e = ep;
+ ep = ep->next;
+ esl_event_safe_destroy(&e);
+ }
+
esl_event_safe_destroy(&handle->last_event);
esl_event_safe_destroy(&handle->last_sr_event);
esl_event_safe_destroy(&handle->last_ievent);
esl_mutex_unlock(mutex);
esl_mutex_destroy(&mutex);
}
-
+
if (handle->packet_buf) {
esl_buffer_destroy(&handle->packet_buf);
}
-
+
+ memset(handle, 0, sizeof(*handle));
+ handle->destroyed = 1;
return status;
}
esl_mutex_unlock(handle->mutex);
}
- activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR);
+ if (handle->packet_buf && esl_buffer_inuse(handle->packet_buf)) {
+ activity = ESL_POLL_READ;
+ } else {
+ activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR);
+ }
if (activity < 0) {
handle->connected = 0;
return ESL_BREAK;
}
- activity = esl_wait_sock(handle->sock, ms, ESL_POLL_READ|ESL_POLL_ERROR);
-
-
if (activity < 0) {
handle->connected = 0;
status = ESL_FAIL;
static esl_ssize_t handle_recv(esl_handle_t *handle, void *data, esl_size_t datalen)
{
- int activity;
+ esl_ssize_t activity = -1;
- while (handle->connected) {
- activity = esl_wait_sock(handle->sock, 1000, ESL_POLL_READ|ESL_POLL_ERROR);
-
- if (activity > 0 && (activity & ESL_POLL_READ)) {
- return recv(handle->sock, data, datalen, 0);
+ if (handle->connected) {
+ if ((activity = esl_wait_sock(handle->sock, -1, ESL_POLL_READ|ESL_POLL_ERROR)) > 0) {
+ if ((activity & ESL_POLL_ERROR)) {
+ activity = -1;
+ } else if ((activity & ESL_POLL_READ)) {
+ activity = recv(handle->sock, data, datalen, 0);
+ if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
+ activity = 0;
+ }
+ }
}
- if (activity < 0) {
- return errno == EINTR ? 0 : -1;
- }
}
- return -1;
+ return activity;
}
ESL_DECLARE(esl_status_t) esl_recv_event(esl_handle_t *handle, int check_q, esl_event_t **save_event)
goto parse_event;
}
-
while(!revent && handle->connected) {
esl_size_t len1;
break;
}
-
- rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1);
- *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, rrval)) = '\0';
+ rrval = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1);
+
if (rrval == 0) {
- if (++zc >= 100) {
- goto fail;
- }
continue;
} else if (rrval < 0) {
if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err))))
goto fail;
}
+ *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, rrval)) = '\0';
zc = 0;
esl_buffer_write(handle->packet_buf, handle->socket_buf, rrval);
sofar = esl_buffer_read(handle->packet_buf, body, len);
} else {
r = handle_recv(handle, handle->socket_buf, sizeof(handle->socket_buf) - 1);
- *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, r)) = '\0';
-
+
if (r < 0) {
if (!(strerror_r(handle->errnum, handle->err, sizeof(handle->err))))
*(handle->err)=0;
goto fail;
} else if (r == 0) {
- if (++zc >= 100) {
- goto fail;
- }
continue;
}
+ *((char *)handle->socket_buf + ESL_CLAMP(0, sizeof(handle->socket_buf) - 1, r)) = '\0';
zc = 0;
esl_buffer_write(handle->packet_buf, handle->socket_buf, r);
esl_event_t *ep;
for(ep = handle->race_event; ep && ep->next; ep = ep->next);
-
+
if (ep) {
ep->next = handle->last_sr_event;
} else {