From 17d1e27d309f16da960fd3b9933e6e2b1db22b17 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 10 Aug 2019 21:20:23 +0000 Subject: [PATCH] asyn-thread: issue CURL_POLL_REMOVE before closing socket This avoids EBADF errors from EPOLL_CTL_DEL operations in the ephiperfifo.c example. EBADF is dangerous in multi-threaded applications where I rely on epoll_ctl to operate on the same epoll description from different threads. Follow-up to eb9a604f8d7db8 Bug: https://curl.haxx.se/mail/lib-2019-08/0026.html Closes #4211 --- lib/asyn-thread.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index 222e78d98..24da74885 100755 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -164,6 +164,7 @@ struct thread_sync_data { duplicate */ int port; #ifdef HAVE_SOCKETPAIR + struct connectdata *conn; curl_socket_t sock_pair[2]; /* socket pair */ #endif int sock_error; @@ -201,11 +202,10 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd) Curl_freeaddrinfo(tsd->res); #ifdef HAVE_SOCKETPAIR - /* close socket pair */ - if(tsd->sock_pair[0] != CURL_SOCKET_BAD) { - sclose(tsd->sock_pair[0]); - } - + /* + * close one end of the socket pair (may be done in resolver thread); + * the other end (for reading) is always closed in the parent thread. + */ if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { sclose(tsd->sock_pair[1]); } @@ -382,6 +382,10 @@ static void destroy_async_data(struct Curl_async *async) if(async->os_specific) { struct thread_data *td = (struct thread_data*) async->os_specific; int done; +#ifdef HAVE_SOCKETPAIR + curl_socket_t sock_rd = td->tsd.sock_pair[0]; + struct connectdata *conn = td->tsd.conn; +#endif /* * if the thread is still blocking in the resolve syscall, detach it and @@ -403,6 +407,15 @@ static void destroy_async_data(struct Curl_async *async) free(async->os_specific); } +#ifdef HAVE_SOCKETPAIR + /* + * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE + * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL + */ + if(conn) + Curl_multi_closed(conn->data, sock_rd); + sclose(sock_rd); +#endif } async->os_specific = NULL; @@ -644,6 +657,8 @@ int Curl_resolver_getsock(struct connectdata *conn, if(td) { /* return read fd to client for polling the DNS resolution status */ socks[0] = td->tsd.sock_pair[0]; + DEBUGASSERT(td->tsd.conn == conn || !td->tsd.conn); + td->tsd.conn = conn; ret_val = GETSOCK_READSOCK(0); } else { -- 2.49.0 From 041690aadb1357775ff06c5bf827a98585627c76 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 30 Jul 2019 10:29:54 +0200 Subject: [PATCH] asyn-thread: removed unused variable Follow-up to eb9a604f. Mistake caused by me when I edited the commit before push... --- lib/asyn-thread.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index f17638e44..e323cbe20 100755 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -636,11 +636,10 @@ int Curl_resolver_getsock(struct connectdata *conn, struct resdata *reslv = (struct resdata *)data->state.resolver; #ifdef HAVE_SOCKETPAIR struct thread_data *td = (struct thread_data*)conn->async.os_specific; - int loop_idx; #else (void)socks; - (void)numsocks; #endif + (void)numsocks; #ifdef HAVE_SOCKETPAIR if(td) { -- 2.49.0 From 060fb84a5a07388f099c7a3422e281ac64d623a5 Mon Sep 17 00:00:00 2001 From: Xiang Xiao Date: Tue, 24 Dec 2019 21:47:37 +0800 Subject: [PATCH] lib: remove erroneous +x file permission on some c files Modified by commit eb9a604 accidentally. Closes https://github.com/curl/curl/pull/4756 --- lib/asyn-thread.c | 0 lib/multi.c | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 lib/asyn-thread.c mode change 100755 => 100644 lib/multi.c diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c old mode 100755 new mode 100644 diff --git a/lib/multi.c b/lib/multi.c old mode 100755 new mode 100644 -- 2.49.0 From e34ec7de5964baa214555115f5061ed199d0f7b4 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 11 Sep 2019 23:11:58 +0200 Subject: [PATCH] asyn-thread: s/AF_LOCAL/AF_UNIX for Solaris Reported-by: Dagobert Michelsen Fixes #4328 Closes #4333 --- lib/asyn-thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index 24da74885..fcbf1305e 100755 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -244,8 +244,8 @@ int init_thread_sync_data(struct thread_data * td, Curl_mutex_init(tsd->mtx); #ifdef HAVE_SOCKETPAIR - /* create socket pair */ - if(socketpair(AF_LOCAL, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { + /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ + if(socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { tsd->sock_pair[0] = CURL_SOCKET_BAD; tsd->sock_pair[1] = CURL_SOCKET_BAD; goto err_exit; -- 2.49.0 From 9c76f694de1765152e0b349cd55baad5a501f55b Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 5 Oct 2019 15:41:09 +0200 Subject: [PATCH] asyn-thread: make use of Curl_socketpair() where available --- lib/asyn-thread.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/asyn-thread.c b/lib/asyn-thread.c index fcbf1305e..8c552baa9 100755 --- a/lib/asyn-thread.c +++ b/lib/asyn-thread.c @@ -163,7 +165,7 @@ struct thread_sync_data { char *hostname; /* hostname to resolve, Curl_async.hostname duplicate */ int port; -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR struct connectdata *conn; curl_socket_t sock_pair[2]; /* socket pair */ #endif @@ -201,7 +203,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd) if(tsd->res) Curl_freeaddrinfo(tsd->res); -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR /* * close one end of the socket pair (may be done in resolver thread); * the other end (for reading) is always closed in the parent thread. @@ -243,9 +245,9 @@ int init_thread_sync_data(struct thread_data * td, Curl_mutex_init(tsd->mtx); -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR /* create socket pair, avoid AF_LOCAL since it doesn't build on Solaris */ - if(socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { + if(Curl_socketpair(AF_UNIX, SOCK_STREAM, 0, &tsd->sock_pair[0]) < 0) { tsd->sock_pair[0] = CURL_SOCKET_BAD; tsd->sock_pair[1] = CURL_SOCKET_BAD; goto err_exit; @@ -297,7 +299,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) struct thread_data *td = tsd->td; char service[12]; int rc; -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR char buf[1]; #endif @@ -322,11 +324,11 @@ static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg) free(td); } else { -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR if(tsd->sock_pair[1] != CURL_SOCKET_BAD) { /* DNS has been resolved, signal client task */ buf[0] = 1; - if(write(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { + if(swrite(tsd->sock_pair[1], buf, sizeof(buf)) < 0) { /* update sock_erro to errno */ tsd->sock_error = SOCKERRNO; } @@ -382,7 +384,7 @@ static void destroy_async_data(struct Curl_async *async) if(async->os_specific) { struct thread_data *td = (struct thread_data*) async->os_specific; int done; -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR curl_socket_t sock_rd = td->tsd.sock_pair[0]; struct connectdata *conn = td->tsd.conn; #endif @@ -407,7 +409,7 @@ static void destroy_async_data(struct Curl_async *async) free(async->os_specific); } -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR /* * ensure CURLMOPT_SOCKETFUNCTION fires CURL_POLL_REMOVE * before the FD is invalidated to avoid EBADF on EPOLL_CTL_DEL @@ -649,14 +651,14 @@ int Curl_resolver_getsock(struct connectdata *conn, timediff_t ms; struct Curl_easy *data = conn->data; struct resdata *reslv = (struct resdata *)data->state.resolver; -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR struct thread_data *td = (struct thread_data*)conn->async.os_specific; #else (void)socks; #endif (void)numsocks; -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR if(td) { /* return read fd to client for polling the DNS resolution status */ socks[0] = td->tsd.sock_pair[0]; @@ -673,7 +675,7 @@ int Curl_resolver_getsock(struct connectdata *conn, else milli = 200; Curl_expire(data, milli, EXPIRE_ASYNC_NAME); -#ifdef HAVE_SOCKETPAIR +#ifdef USE_SOCKETPAIR } #endif -- 2.49.0