mirror of
https://github.com/curl/curl.git
synced 2026-04-11 12:01:42 +08:00
examples: omit forward declarations, apply misc fixes
- reorder functions to not need forward declarations. - sync `ephiperfifo.c` and `evhiperfifo.c`. - drop redundant casts for `calloc()` return value. - ephiperfifo: silence unused variable warning. - fix indent and apply clang-format more. Closes #20296
This commit is contained in:
parent
df246eeb8f
commit
8680a07589
@ -110,7 +110,7 @@ static struct ip *ip_list_append(struct ip *list, const char *data)
|
||||
struct ip *ip, *last;
|
||||
char *cidr;
|
||||
|
||||
ip = (struct ip *)calloc(1, sizeof(*ip));
|
||||
ip = calloc(1, sizeof(*ip));
|
||||
if(!ip)
|
||||
return NULL;
|
||||
|
||||
@ -296,7 +296,7 @@ int main(void)
|
||||
CURLcode result;
|
||||
struct connection_filter *filter;
|
||||
|
||||
filter = (struct connection_filter *)calloc(1, sizeof(*filter));
|
||||
filter = calloc(1, sizeof(*filter));
|
||||
if(!filter)
|
||||
return 1;
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket API usage with epoll and timerfd
|
||||
* multi socket interface with epoll and timerfd
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
@ -140,7 +140,61 @@ static void mcode_or_die(const char *where, CURLMcode code)
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_cb(struct GlobalInfo *g, int revents);
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(struct GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
struct ConnInfo *conn;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
CURL *curl = msg->easy_handle;
|
||||
CURLcode result = msg->data.result;
|
||||
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, result, conn->error);
|
||||
curl_multi_remove_handle(g->multi, curl);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(curl);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by main loop when our timeout expires */
|
||||
static void timer_cb(struct GlobalInfo *g, int revents)
|
||||
{
|
||||
CURLMcode mresult;
|
||||
uint64_t count = 0;
|
||||
ssize_t err = 0;
|
||||
|
||||
(void)revents;
|
||||
|
||||
err = read(g->tfd, &count, sizeof(uint64_t));
|
||||
if(err == -1) {
|
||||
/* Note that we may call the timer callback even if the timerfd is not
|
||||
* readable. It is possible that there are multiple events stored in the
|
||||
* epoll buffer (i.e. the timer may have fired multiple times). The event
|
||||
* count is cleared after the first call so future events in the epoll
|
||||
* buffer fails to read from the timer. */
|
||||
if(errno == EAGAIN) {
|
||||
fprintf(MSG_OUT, "EAGAIN on tfd %d\n", g->tfd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(err != sizeof(uint64_t)) {
|
||||
fprintf(stderr, "read(tfd) == %ld", err);
|
||||
perror("read(tfd)");
|
||||
}
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0,
|
||||
&g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", mresult);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Update the timer after curl_multi library does its thing. curl informs the
|
||||
* application through this callback what it wants the new timeout to be,
|
||||
@ -149,6 +203,8 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g)
|
||||
{
|
||||
struct itimerspec its;
|
||||
|
||||
(void)multi;
|
||||
|
||||
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
|
||||
|
||||
if(timeout_ms > 0) {
|
||||
@ -174,30 +230,6 @@ static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(struct GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
struct ConnInfo *conn;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
CURL *curl = msg->easy_handle;
|
||||
CURLcode result = msg->data.result;
|
||||
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, result, conn->error);
|
||||
curl_multi_remove_handle(g->multi, curl);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(curl);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when we get action on a multi socket filedescriptor */
|
||||
static void event_cb(struct GlobalInfo *g, int fd, int revents)
|
||||
{
|
||||
@ -205,7 +237,7 @@ static void event_cb(struct GlobalInfo *g, int fd, int revents)
|
||||
struct itimerspec its;
|
||||
|
||||
int action = ((revents & EPOLLIN) ? CURL_CSELECT_IN : 0) |
|
||||
((revents & EPOLLOUT) ? CURL_CSELECT_OUT : 0);
|
||||
((revents & EPOLLOUT) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", mresult);
|
||||
@ -218,36 +250,6 @@ static void event_cb(struct GlobalInfo *g, int fd, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by main loop when our timeout expires */
|
||||
static void timer_cb(struct GlobalInfo *g, int revents)
|
||||
{
|
||||
CURLMcode mresult;
|
||||
uint64_t count = 0;
|
||||
ssize_t err = 0;
|
||||
|
||||
err = read(g->tfd, &count, sizeof(uint64_t));
|
||||
if(err == -1) {
|
||||
/* Note that we may call the timer callback even if the timerfd is not
|
||||
* readable. It is possible that there are multiple events stored in the
|
||||
* epoll buffer (i.e. the timer may have fired multiple times). The event
|
||||
* count is cleared after the first call so future events in the epoll
|
||||
* buffer fails to read from the timer. */
|
||||
if(errno == EAGAIN) {
|
||||
fprintf(MSG_OUT, "EAGAIN on tfd %d\n", g->tfd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(err != sizeof(uint64_t)) {
|
||||
fprintf(stderr, "read(tfd) == %ld", err);
|
||||
perror("read(tfd)");
|
||||
}
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", mresult);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(struct SockInfo *f, struct GlobalInfo *g)
|
||||
{
|
||||
@ -290,7 +292,7 @@ static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
static void addsock(curl_socket_t s, CURL *curl, int action,
|
||||
struct GlobalInfo *g)
|
||||
{
|
||||
struct SockInfo *fdp = (struct SockInfo *)calloc(1, sizeof(struct SockInfo));
|
||||
struct SockInfo *fdp = calloc(1, sizeof(struct SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, curl, action, g);
|
||||
@ -349,7 +351,7 @@ static void new_conn(const char *url, struct GlobalInfo *g)
|
||||
struct ConnInfo *conn;
|
||||
CURLMcode mresult;
|
||||
|
||||
conn = (struct ConnInfo *)calloc(1, sizeof(*conn));
|
||||
conn = calloc(1, sizeof(*conn));
|
||||
conn->error[0] = '\0';
|
||||
|
||||
conn->curl = curl_easy_init();
|
||||
@ -371,13 +373,14 @@ static void new_conn(const char *url, struct GlobalInfo *g)
|
||||
curl_easy_setopt(conn->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(conn->curl, CURLOPT_LOW_SPEED_TIME, 3L);
|
||||
curl_easy_setopt(conn->curl, CURLOPT_LOW_SPEED_LIMIT, 10L);
|
||||
|
||||
fprintf(MSG_OUT, "Adding easy %p to multi %p (%s)\n",
|
||||
conn->curl, g->multi, url);
|
||||
mresult = curl_multi_add_handle(g->multi, conn->curl);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", mresult);
|
||||
|
||||
/* note that the add_handle() sets a timeout to trigger soon so that the
|
||||
* necessary socket_action() call gets called by this app */
|
||||
/* note that add_handle() sets a timeout to trigger soon so that the
|
||||
necessary socket_action() gets called */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
@ -387,6 +390,8 @@ static void fifo_cb(struct GlobalInfo *g, int revents)
|
||||
long int rv = 0;
|
||||
int n = 0;
|
||||
|
||||
(void)revents;
|
||||
|
||||
do {
|
||||
s[0] = '\0';
|
||||
rv = fscanf(g->input, "%1023s%n", s, &n);
|
||||
@ -400,10 +405,10 @@ static void fifo_cb(struct GlobalInfo *g, int revents)
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static const char *fifo = "hiper.fifo";
|
||||
static int init_fifo(struct GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
curl_socket_t sockfd;
|
||||
struct epoll_event epev;
|
||||
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket interface together with libev
|
||||
* multi socket interface with libev
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
@ -106,23 +106,6 @@ struct SockInfo {
|
||||
struct GlobalInfo *global;
|
||||
};
|
||||
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents);
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g)
|
||||
{
|
||||
(void)multi;
|
||||
printf("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
if(timeout_ms >= 0) {
|
||||
/* -1 means delete, other values are timeout times in milliseconds */
|
||||
double t = timeout_ms / 1000;
|
||||
ev_timer_init(&g->timer_event, timer_cb, t, 0.);
|
||||
ev_timer_start(g->loop, &g->timer_event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
@ -185,18 +168,49 @@ static void check_multi_info(struct GlobalInfo *g)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents)
|
||||
{
|
||||
CURLMcode mresult;
|
||||
struct GlobalInfo *g;
|
||||
|
||||
printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents);
|
||||
|
||||
g = (struct GlobalInfo *)w->data;
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0,
|
||||
&g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", mresult);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, struct GlobalInfo *g)
|
||||
{
|
||||
(void)multi;
|
||||
printf("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
if(timeout_ms >= 0) {
|
||||
/* -1 means delete, other values are timeout times in milliseconds */
|
||||
double t = timeout_ms / 1000;
|
||||
ev_timer_init(&g->timer_event, timer_cb, t, 0.);
|
||||
ev_timer_start(g->loop, &g->timer_event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
struct GlobalInfo *g;
|
||||
CURLMcode mresult;
|
||||
int action;
|
||||
struct GlobalInfo *g;
|
||||
|
||||
int action = ((revents & EV_READ) ? CURL_POLL_IN : 0) |
|
||||
((revents & EV_WRITE) ? CURL_POLL_OUT : 0);
|
||||
|
||||
printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents);
|
||||
g = (struct GlobalInfo *)w->data;
|
||||
|
||||
action = ((revents & EV_READ) ? CURL_POLL_IN : 0) |
|
||||
((revents & EV_WRITE) ? CURL_POLL_OUT : 0);
|
||||
mresult = curl_multi_socket_action(g->multi, w->fd, action,
|
||||
&g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", mresult);
|
||||
@ -207,22 +221,6 @@ static void event_cb(EV_P_ struct ev_io *w, int revents)
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents)
|
||||
{
|
||||
struct GlobalInfo *g;
|
||||
CURLMcode mresult;
|
||||
|
||||
printf("%s w %p revents %i\n", __PRETTY_FUNCTION__, (void *)w, revents);
|
||||
|
||||
g = (struct GlobalInfo *)w->data;
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0,
|
||||
&g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", mresult);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(struct SockInfo *f, struct GlobalInfo *g)
|
||||
{
|
||||
@ -370,7 +368,7 @@ static void fifo_cb(EV_P_ struct ev_io *w, int revents)
|
||||
rv = fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n] = '\0';
|
||||
if(n && s[0]) {
|
||||
new_conn(s, g); /* if we read a URL, go get it! */
|
||||
new_conn(s, g); /* if we read a URL, go get it! */
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket API usage together with glib2
|
||||
* multi socket API usage with glib2
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
@ -194,9 +194,8 @@ static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
CURLMcode mresult;
|
||||
int fd = g_io_channel_unix_get_fd(ch);
|
||||
|
||||
int action =
|
||||
((condition & G_IO_IN) ? CURL_CSELECT_IN : 0) |
|
||||
((condition & G_IO_OUT) ? CURL_CSELECT_OUT : 0);
|
||||
int action = ((condition & G_IO_IN) ? CURL_CSELECT_IN : 0) |
|
||||
((condition & G_IO_OUT) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", mresult);
|
||||
@ -230,9 +229,8 @@ static void remsock(struct SockInfo *f)
|
||||
static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
struct GlobalInfo *g)
|
||||
{
|
||||
GIOCondition kind =
|
||||
((act & CURL_POLL_IN) ? G_IO_IN : 0) |
|
||||
((act & CURL_POLL_OUT) ? G_IO_OUT : 0);
|
||||
GIOCondition kind = ((act & CURL_POLL_IN) ? G_IO_IN : 0) |
|
||||
((act & CURL_POLL_OUT) ? G_IO_OUT : 0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
|
||||
@ -198,9 +198,8 @@ static void event_cb(int fd, short kind, void *userp)
|
||||
struct GlobalInfo *g = (struct GlobalInfo *)userp;
|
||||
CURLMcode mresult;
|
||||
|
||||
int action =
|
||||
((kind & EV_READ) ? CURL_CSELECT_IN : 0) |
|
||||
((kind & EV_WRITE) ? CURL_CSELECT_OUT : 0);
|
||||
int action = ((kind & EV_READ) ? CURL_CSELECT_IN : 0) |
|
||||
((kind & EV_WRITE) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
mresult = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", mresult);
|
||||
@ -243,9 +242,8 @@ static void remsock(struct SockInfo *f)
|
||||
static void setsock(struct SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
struct GlobalInfo *g)
|
||||
{
|
||||
int kind =
|
||||
((act & CURL_POLL_IN) ? EV_READ : 0) |
|
||||
((act & CURL_POLL_OUT) ? EV_WRITE : 0) | EV_PERSIST;
|
||||
int kind = ((act & CURL_POLL_IN) ? EV_READ : 0) |
|
||||
((act & CURL_POLL_OUT) ? EV_WRITE : 0) | EV_PERSIST;
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
@ -371,7 +369,7 @@ static void fifo_cb(int fd, short event, void *arg)
|
||||
event_base_loopbreak(g->evbase);
|
||||
}
|
||||
else
|
||||
new_conn(s, arg); /* if we read a URL, go get it! */
|
||||
new_conn(s, arg); /* if we read a URL, go get it! */
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
@ -41,50 +41,6 @@ struct curl_context {
|
||||
curl_socket_t sockfd;
|
||||
};
|
||||
|
||||
static void curl_perform(int fd, short event, void *arg);
|
||||
|
||||
static struct curl_context *create_curl_context(curl_socket_t sockfd)
|
||||
{
|
||||
struct curl_context *context;
|
||||
|
||||
context = (struct curl_context *)malloc(sizeof(*context));
|
||||
|
||||
context->sockfd = sockfd;
|
||||
|
||||
context->event = event_new(base, sockfd, 0, curl_perform, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void destroy_curl_context(struct curl_context *context)
|
||||
{
|
||||
event_del(context->event);
|
||||
event_free(context->event);
|
||||
free(context);
|
||||
}
|
||||
|
||||
static void add_download(const char *url, int num)
|
||||
{
|
||||
char filename[50];
|
||||
FILE *file;
|
||||
CURL *curl;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%d.download", num);
|
||||
|
||||
file = fopen(filename, "wb");
|
||||
if(!file) {
|
||||
fprintf(stderr, "Error opening %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
|
||||
curl_easy_setopt(curl, CURLOPT_PRIVATE, file);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_multi_add_handle(multi, curl);
|
||||
fprintf(stderr, "Added download %s -> %s\n", url, filename);
|
||||
}
|
||||
|
||||
static void check_multi_info(void)
|
||||
{
|
||||
char *done_url;
|
||||
@ -141,6 +97,48 @@ static void curl_perform(int fd, short event, void *arg)
|
||||
check_multi_info();
|
||||
}
|
||||
|
||||
static struct curl_context *create_curl_context(curl_socket_t sockfd)
|
||||
{
|
||||
struct curl_context *context;
|
||||
|
||||
context = (struct curl_context *)malloc(sizeof(*context));
|
||||
|
||||
context->sockfd = sockfd;
|
||||
|
||||
context->event = event_new(base, sockfd, 0, curl_perform, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void destroy_curl_context(struct curl_context *context)
|
||||
{
|
||||
event_del(context->event);
|
||||
event_free(context->event);
|
||||
free(context);
|
||||
}
|
||||
|
||||
static void add_download(const char *url, int num)
|
||||
{
|
||||
char filename[50];
|
||||
FILE *file;
|
||||
CURL *curl;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%d.download", num);
|
||||
|
||||
file = fopen(filename, "wb");
|
||||
if(!file) {
|
||||
fprintf(stderr, "Error opening %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
|
||||
curl_easy_setopt(curl, CURLOPT_PRIVATE, file);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_multi_add_handle(multi, curl);
|
||||
fprintf(stderr, "Added download %s -> %s\n", url, filename);
|
||||
}
|
||||
|
||||
static void on_timeout(evutil_socket_t fd, short events, void *arg)
|
||||
{
|
||||
int running_handles;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user