mirror of
https://github.com/curl/curl.git
synced 2026-07-23 21:57:21 +03:00
socketpair: cleaner interface
Declutter the ifdefs in socketpair.h. Introduce Curl_wakeup_*() function that encapsulate the details about how the socketpair is implemented. This moves the EVENTFD specials from the using code into socketpair implemenatation, avoiding duplications in three places. Closes #20340
This commit is contained in:
parent
1a57302d1a
commit
6c8956c1cb
4 changed files with 144 additions and 138 deletions
137
lib/socketpair.c
137
lib/socketpair.c
|
|
@ -28,11 +28,14 @@
|
|||
#include "rand.h"
|
||||
#include "curlx/nonblock.h"
|
||||
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
|
||||
/* choose implementation */
|
||||
#ifdef USE_EVENTFD
|
||||
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
int Curl_eventfd(curl_socket_t socks[2], bool nonblocking)
|
||||
static int wakeup_eventfd(curl_socket_t socks[2], bool nonblocking)
|
||||
{
|
||||
int efd = eventfd(0, nonblocking ? EFD_CLOEXEC | EFD_NONBLOCK : EFD_CLOEXEC);
|
||||
if(efd == -1) {
|
||||
|
|
@ -49,7 +52,7 @@ int Curl_eventfd(curl_socket_t socks[2], bool nonblocking)
|
|||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
int Curl_pipe(curl_socket_t socks[2], bool nonblocking)
|
||||
static int wakeup_pipe(curl_socket_t socks[2], bool nonblocking)
|
||||
{
|
||||
#ifdef HAVE_PIPE2
|
||||
int flags = nonblocking ? O_NONBLOCK | O_CLOEXEC : O_CLOEXEC;
|
||||
|
|
@ -81,18 +84,24 @@ int Curl_pipe(curl_socket_t socks[2], bool nonblocking)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif /* USE_EVENTFD */
|
||||
#elif defined(HAVE_SOCKETPAIR) /* !USE_EVENTFD && !HAVE_PIPE */
|
||||
|
||||
#ifndef CURL_DISABLE_SOCKETPAIR
|
||||
#ifdef HAVE_SOCKETPAIR
|
||||
#ifdef USE_SOCKETPAIR
|
||||
int Curl_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socks[2], bool nonblocking)
|
||||
{
|
||||
#ifdef SOCK_NONBLOCK
|
||||
type = nonblocking ? type | SOCK_NONBLOCK : type;
|
||||
#ifndef USE_UNIX_SOCKETS
|
||||
#error "unsupported Unix domain and socketpair build combo"
|
||||
#endif
|
||||
if(CURL_SOCKETPAIR(domain, type, protocol, socks))
|
||||
|
||||
static int wakeup_socketpair(curl_socket_t socks[2], bool nonblocking)
|
||||
{
|
||||
int type = SOCK_STREAM;
|
||||
#ifdef SOCK_CLOEXEC
|
||||
type |= SOCK_CLOEXEC;
|
||||
#endif
|
||||
#ifdef SOCK_NONBLOCK
|
||||
if(nonblocking)
|
||||
type |= SOCK_NONBLOCK;
|
||||
#endif
|
||||
|
||||
if(CURL_SOCKETPAIR(AF_UNIX, type, 0, socks))
|
||||
return -1;
|
||||
#ifndef SOCK_NONBLOCK
|
||||
if(nonblocking) {
|
||||
|
|
@ -106,8 +115,8 @@ int Curl_socketpair(int domain, int type, int protocol,
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_SOCKETPAIR */
|
||||
#else /* !HAVE_SOCKETPAIR */
|
||||
|
||||
#else /* !USE_EVENTFD && !HAVE_PIPE && !HAVE_SOCKETPAIR */
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
|
|
@ -125,8 +134,7 @@ int Curl_socketpair(int domain, int type, int protocol,
|
|||
|
||||
#include "select.h" /* for Curl_poll */
|
||||
|
||||
int Curl_socketpair(int domain, int type, int protocol,
|
||||
curl_socket_t socks[2], bool nonblocking)
|
||||
static int wakeup_inet(curl_socket_t socks[2], bool nonblocking)
|
||||
{
|
||||
union {
|
||||
struct sockaddr_in inaddr;
|
||||
|
|
@ -136,9 +144,6 @@ int Curl_socketpair(int domain, int type, int protocol,
|
|||
curl_socklen_t addrlen = sizeof(a.inaddr);
|
||||
int reuse = 1;
|
||||
struct pollfd pfd[1];
|
||||
(void)domain;
|
||||
(void)type;
|
||||
(void)protocol;
|
||||
|
||||
listener = CURL_SOCKET(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(listener == CURL_SOCKET_BAD)
|
||||
|
|
@ -257,5 +262,99 @@ error:
|
|||
sclose(socks[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* choose implementation */
|
||||
|
||||
int Curl_wakeup_init(curl_socket_t socks[2], bool nonblocking)
|
||||
{
|
||||
#ifdef USE_EVENTFD
|
||||
return wakeup_eventfd(socks, nonblocking);
|
||||
#elif defined(HAVE_PIPE)
|
||||
return wakeup_pipe(socks, nonblocking);
|
||||
#elif defined(HAVE_SOCKETPAIR)
|
||||
return wakeup_socketpair(socks, nonblocking);
|
||||
#else
|
||||
return wakeup_inet(socks, nonblocking);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(USE_EVENTFD) || defined(HAVE_PIPE)
|
||||
|
||||
#define wakeup_write write
|
||||
#define wakeup_read read
|
||||
#define wakeup_close close
|
||||
|
||||
#else /* !USE_EVENTFD && !HAVE_PIPE */
|
||||
|
||||
#define wakeup_write swrite
|
||||
#define wakeup_read sread
|
||||
#define wakeup_close sclose
|
||||
|
||||
#endif
|
||||
|
||||
int Curl_wakeup_signal(curl_socket_t socks[2])
|
||||
{
|
||||
int err = 0;
|
||||
#ifdef USE_EVENTFD
|
||||
const uint64_t buf[1] = { 1 };
|
||||
#else
|
||||
const char buf[1] = { 1 };
|
||||
#endif
|
||||
|
||||
while(1) {
|
||||
if(wakeup_write(socks[1], buf, sizeof(buf)) < 0) {
|
||||
err = SOCKERRNO;
|
||||
#ifdef USE_WINSOCK
|
||||
if(err == SOCKEWOULDBLOCK)
|
||||
err = 0; /* wakeup is already ongoing */
|
||||
#else
|
||||
if(SOCKEINTR == err)
|
||||
continue;
|
||||
if((err == SOCKEWOULDBLOCK) || (err == EAGAIN))
|
||||
err = 0; /* wakeup is already ongoing */
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
CURLcode Curl_wakeup_consume(curl_socket_t socks[2], bool all)
|
||||
{
|
||||
char buf[64];
|
||||
ssize_t rc;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
do {
|
||||
rc = wakeup_read(socks[0], buf, sizeof(buf));
|
||||
if(!rc)
|
||||
break;
|
||||
else if(rc < 0) {
|
||||
#ifdef USE_WINSOCK
|
||||
if(SOCKERRNO == SOCKEWOULDBLOCK)
|
||||
break;
|
||||
#else
|
||||
if(SOCKEINTR == SOCKERRNO)
|
||||
continue;
|
||||
if((SOCKERRNO == SOCKEWOULDBLOCK) || (SOCKERRNO == EAGAIN))
|
||||
break;
|
||||
#endif
|
||||
result = CURLE_READ_ERROR;
|
||||
break;
|
||||
}
|
||||
} while(all);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Curl_wakeup_destroy(curl_socket_t socks[2])
|
||||
{
|
||||
#ifndef USE_EVENTFD
|
||||
if(socks[1] != CURL_SOCKET_BAD)
|
||||
wakeup_close(socks[1]);
|
||||
#endif
|
||||
if(socks[0] != CURL_SOCKET_BAD)
|
||||
wakeup_close(socks[0]);
|
||||
socks[0] = socks[1] = CURL_SOCKET_BAD;
|
||||
}
|
||||
|
||||
#endif /* !CURL_DISABLE_SOCKETPAIR */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue