Patch from Christopher Davis.
svn:r1444
o Try to compile better with MSVC: patches from Brodie Thiesfield
o New evconnlistener_get_fd function to expose a listener's associated socket.
o Expose an ev_socklen_t type for consistent use across platforms.
- o Make bufferevenr_socket_connect() work when the original fd was -1.
+ o Make bufferevent_socket_connect() work when the original fd was -1.
o Fix a bug in bufferevent_socket_connect() when the connection succeeds too quickly.
o Export an evutil_sockaddr_cmp() to compare to sockaddr objects for equality.
o Add a bufferevent_get_enabled() to tell what a bufferevent has been configured to do.
o New event_base_got_exit() and event_base_got_break() functions to tell whether an event loop exited because of an event_base_loopexit() or an event_base_loopbreak(). Patch from Ka-Hing Cheung.
o When adding or deleting an event from a non-main thread, only wake up the main thread when its behavior actually needs to change.
o Fix some bugs when using the old evdns interfaces to initialize the evdns module.
+ o Detect errors during bufferevent_connect(). Patch from Christopher Davis.
Changes in 2.0.2-alpha:
goto error;
}
if (bufev_p->connecting) {
+ int c = evutil_socket_finished_connecting(fd);
+
+ if (c == 0)
+ goto done;
+
bufev_p->connecting = 0;
- connected = 1;
- _bufferevent_run_eventcb(bufev, BEV_EVENT_CONNECTED);
- if (!(bufev->enabled & EV_WRITE)) {
+ if (c < 0) {
event_del(&bufev->ev_write);
+ event_del(&bufev->ev_read);
+ _bufferevent_run_eventcb(bufev, BEV_EVENT_ERROR);
goto done;
+ } else {
+ connected = 1;
+ _bufferevent_run_eventcb(bufev, BEV_EVENT_CONNECTED);
+ if (!(bufev->enabled & EV_WRITE)) {
+ event_del(&bufev->ev_write);
+ goto done;
+ }
}
}
return -1;
}
+/* Check whether a socket on which we called connect() is done
+ connecting. Return 1 for connected, 0 for not yet, -1 for error. In the
+ error case, set the current socket errno to the error that happened during
+ the connect operation. */
+int
+evutil_socket_finished_connecting(evutil_socket_t fd)
+{
+ int e;
+ ev_socklen_t elen = sizeof(e);
+
+ if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&e, &elen) < 0)
+ return -1;
+
+ if (e) {
+ if (EVUTIL_ERR_CONNECT_RETRIABLE(e))
+ return 0;
+ EVUTIL_SET_SOCKET_ERROR(e);
+ return -1;
+ }
+
+ return 1;
+}
+
#ifdef WIN32
#define E(code, s) { code, (s " [" #code " ]") }
static struct { int code; const char *msg; } windows_socket_errors[] = {
int evutil_socket_connect(evutil_socket_t *fd_ptr, struct sockaddr *sa, int socklen);
+int evutil_socket_finished_connecting(evutil_socket_t fd);
+
#ifdef __cplusplus
}
#endif