Non-blocking connect

This commit is contained in:
Florian Märkl 2019-10-28 19:40:21 +01:00
parent e2fc84e0e6
commit 042e698749
No known key found for this signature in database
GPG Key ID: 125BC8A5A6A1E857
15 changed files with 266 additions and 72 deletions

@ -2,6 +2,7 @@
set(HEADER_FILES
include/chiaki/session.h
include/chiaki/common.h
include/chiaki/sock.h
include/chiaki/thread.h
include/chiaki/base64.h
include/chiaki/http.h
@ -37,6 +38,7 @@ set(HEADER_FILES
set(SOURCE_FILES
src/common.c
src/sock.c
src/session.c
src/thread.c
src/base64.c

@ -18,27 +18,14 @@
#ifndef CHIAKI_COMMON_H
#define CHIAKI_COMMON_H
#include <stdbool.h>
#ifdef _WIN32
#define chiaki_socket_t SOCKET
#define CHIAKI_SOCKET_IS_INVALID(s) ((s) == INVALID_SOCKET)
#define CHIAKI_INVALID_SOCKET INVALID_SOCKET
#define CHIAKI_SOCKET_CLOSE(s) closesocket(s)
#define CHIAKI_SOCKET_ERROR_FMT "%d"
#define CHIAKI_SOCKET_ERROR_VALUE (WSAGetLastError())
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#else
#include <unistd.h>
#define chiaki_socket_t int
#define CHIAKI_SOCKET_IS_INVALID(s) ((s) < 0)
#define CHIAKI_INVALID_SOCKET (-1)
#define CHIAKI_SOCKET_CLOSE(s) close(s)
#define CHIAKI_SOCKET_ERROR_FMT "%s"
#define CHIAKI_SOCKET_ERROR_VALUE (strerror(errno))
#endif
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -56,6 +43,9 @@ typedef enum
CHIAKI_ERR_MEMORY,
CHIAKI_ERR_OVERFLOW,
CHIAKI_ERR_NETWORK,
CHIAKI_ERR_CONNECTION_REFUSED,
CHIAKI_ERR_HOST_DOWN,
CHIAKI_ERR_HOST_UNREACH,
CHIAKI_ERR_DISCONNECTED,
CHIAKI_ERR_INVALID_DATA,
CHIAKI_ERR_BUF_TOO_SMALL,

56
lib/include/chiaki/sock.h Normal file

@ -0,0 +1,56 @@
/*
* This file is part of Chiaki.
*
* Chiaki is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chiaki is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef CHIAKI_SOCK_H
#define CHIAKI_SOCK_H
#include "common.h"
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
#include <winsock2.h>
typedef SOCKET chiaki_socket_t;
#define CHIAKI_SOCKET_IS_INVALID(s) ((s) == INVALID_SOCKET)
#define CHIAKI_INVALID_SOCKET INVALID_SOCKET
#define CHIAKI_SOCKET_CLOSE(s) closesocket(s)
#define CHIAKI_SOCKET_ERROR_FMT "%d"
#define CHIAKI_SOCKET_ERROR_VALUE (WSAGetLastError())
#define CHIAKI_SOCKET_EINPROGRESS (WSAGetLastError() == WSAEWOULDBLOCK)
#else
#include <unistd.h>
#include <errno.h>
typedef int chiaki_socket_t;
#define CHIAKI_SOCKET_IS_INVALID(s) ((s) < 0)
#define CHIAKI_INVALID_SOCKET (-1)
#define CHIAKI_SOCKET_CLOSE(s) close(s)
#define CHIAKI_SOCKET_ERROR_FMT "%s"
#define CHIAKI_SOCKET_ERROR_VALUE (strerror(errno))
#define CHIAKI_SOCKET_EINPROGRESS (errno == EINPROGRESS)
#endif
CHIAKI_EXPORT ChiakiErrorCode chiaki_socket_set_nonblock(chiaki_socket_t sock, bool nonblock);
#ifdef __cplusplus
}
#endif
#endif //CHIAKI_SOCK_H

@ -18,10 +18,11 @@
#ifndef CHIAKI_STOPPIPE_H
#define CHIAKI_STOPPIPE_H
#include "common.h"
#include "sock.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef _WIN32
#include <winsock2.h>
@ -40,11 +41,17 @@ typedef struct chiaki_stop_pipe_t
#endif
} ChiakiStopPipe;
struct sockaddr;
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_init(ChiakiStopPipe *stop_pipe);
CHIAKI_EXPORT void chiaki_stop_pipe_fini(ChiakiStopPipe *stop_pipe);
CHIAKI_EXPORT void chiaki_stop_pipe_stop(ChiakiStopPipe *stop_pipe);
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, uint64_t timeout_ms);
static inline ChiakiErrorCode chiaki_stop_pipe_sleep(ChiakiStopPipe *stop_pipe, uint64_t timeout_ms) { return chiaki_stop_pipe_select_single(stop_pipe, CHIAKI_INVALID_SOCKET, timeout_ms); }
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, bool write, uint64_t timeout_ms);
/**
* Like connect(), but can be canceled by the stop pipe. Only makes sense with a non-blocking socket.
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_connect(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, struct sockaddr *addr, size_t addrlen);
static inline ChiakiErrorCode chiaki_stop_pipe_sleep(ChiakiStopPipe *stop_pipe, uint64_t timeout_ms) { return chiaki_stop_pipe_select_single(stop_pipe, CHIAKI_INVALID_SOCKET, false, timeout_ms); }
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_reset(ChiakiStopPipe *stop_pipe);
#ifdef __cplusplus

@ -213,7 +213,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send(ChiakiTakion *takion, uint8_t *
/**
* Thread-safe while Takion is running.
*
* @param optional pointer to write the sequence number of the sent package to
* @param optional pointer to write the sequence number of the sent packet to
*/
CHIAKI_EXPORT ChiakiErrorCode chiaki_takion_send_message_data(ChiakiTakion *takion, uint8_t chunk_flags, uint16_t channel, uint8_t *buf, size_t buf_size, ChiakiSeqNum32 *seq_num);

@ -43,6 +43,12 @@ CHIAKI_EXPORT const char *chiaki_error_string(ChiakiErrorCode code)
return "Memory error";
case CHIAKI_ERR_NETWORK:
return "Network error";
case CHIAKI_ERR_CONNECTION_REFUSED:
return "Connection Refused";
case CHIAKI_ERR_HOST_DOWN:
return "Host is down";
case CHIAKI_ERR_HOST_UNREACH:
return "No route to host";
case CHIAKI_ERR_DISCONNECTED:
return "Disconnected";
case CHIAKI_ERR_INVALID_DATA:

@ -151,18 +151,19 @@ static void *ctrl_thread_func(void *user)
{
ChiakiCtrl *ctrl = user;
ChiakiErrorCode err = ctrl_connect(ctrl);
ChiakiErrorCode err = chiaki_mutex_lock(&ctrl->notif_mutex);
assert(err == CHIAKI_ERR_SUCCESS);
err = ctrl_connect(ctrl);
if(err != CHIAKI_ERR_SUCCESS)
{
ctrl_failed(ctrl, CHIAKI_QUIT_REASON_CTRL_CONNECT_FAILED);
chiaki_mutex_unlock(&ctrl->notif_mutex);
return NULL;
}
CHIAKI_LOGI(ctrl->session->log, "Ctrl connected");
err = chiaki_mutex_lock(&ctrl->notif_mutex);
assert(err == CHIAKI_ERR_SUCCESS);
while(true)
{
bool overflow = false;
@ -197,7 +198,7 @@ static void *ctrl_thread_func(void *user)
}
chiaki_mutex_unlock(&ctrl->notif_mutex);
err = chiaki_stop_pipe_select_single(&ctrl->notif_pipe, ctrl->sock, UINT64_MAX);
err = chiaki_stop_pipe_select_single(&ctrl->notif_pipe, ctrl->sock, false, UINT64_MAX);
chiaki_mutex_lock(&ctrl->notif_mutex);
if(err == CHIAKI_ERR_CANCELED)
{
@ -511,29 +512,38 @@ static ChiakiErrorCode ctrl_connect(ChiakiCtrl *ctrl)
return CHIAKI_ERR_NETWORK;
}
int r = connect(sock, sa, addr->ai_addrlen);
ChiakiErrorCode err = chiaki_socket_set_nonblock(sock, true);
if(err != CHIAKI_ERR_SUCCESS)
CHIAKI_LOGE(session->log, "Failed to set ctrl socket to non-blocking: %s", chiaki_error_string(err));
chiaki_mutex_unlock(&ctrl->notif_mutex);
err = chiaki_stop_pipe_connect(&ctrl->notif_pipe, sock, sa, addr->ai_addrlen);
chiaki_mutex_lock(&ctrl->notif_mutex);
free(sa);
if(r < 0)
if(err != CHIAKI_ERR_SUCCESS)
{
#ifdef _WIN32
int errsv = WSAGetLastError();
CHIAKI_LOGE(session->log, "Ctrl connect failed: %d", errsv);
ChiakiQuitReason quit_reason = errsv == WSAECONNREFUSED ? CHIAKI_QUIT_REASON_CTRL_CONNECTION_REFUSED : CHIAKI_QUIT_REASON_CTRL_UNKNOWN;
#else
int errsv = errno;
CHIAKI_LOGE(session->log, "Ctrl connect failed: %s", strerror(errsv));
ChiakiQuitReason quit_reason = errsv == ECONNREFUSED ? CHIAKI_QUIT_REASON_CTRL_CONNECTION_REFUSED : CHIAKI_QUIT_REASON_CTRL_UNKNOWN;
#endif
ctrl_failed(ctrl, quit_reason);
CHIAKI_SOCKET_CLOSE(sock);
return CHIAKI_ERR_NETWORK;
if(err == CHIAKI_ERR_CANCELED)
{
if(ctrl->should_stop)
CHIAKI_LOGI(session->log, "Ctrl requested to stop while connecting");
else
CHIAKI_LOGE(session->log, "Ctrl notif pipe signaled without should_stop during connect");
CHIAKI_SOCKET_CLOSE(sock);
}
else
{
CHIAKI_LOGE(session->log, "Ctrl connect failed: %s", chiaki_error_string(err));
ChiakiQuitReason quit_reason = err == CHIAKI_ERR_CONNECTION_REFUSED ? CHIAKI_QUIT_REASON_CTRL_CONNECTION_REFUSED : CHIAKI_QUIT_REASON_CTRL_UNKNOWN;
ctrl_failed(ctrl, quit_reason);
}
goto error;
}
CHIAKI_LOGI(session->log, "Connected to %s:%d", session->connect_info.hostname, SESSION_CTRL_PORT);
CHIAKI_LOGI(session->log, "Ctrl connected to %s:%d", session->connect_info.hostname, SESSION_CTRL_PORT);
uint8_t auth_enc[CHIAKI_RPCRYPT_KEY_SIZE];
ChiakiErrorCode err = chiaki_rpcrypt_encrypt(&session->rpcrypt, ctrl->crypt_counter_local++, (const uint8_t *)session->connect_info.regist_key, auth_enc, CHIAKI_RPCRYPT_KEY_SIZE);
err = chiaki_rpcrypt_encrypt(&session->rpcrypt, ctrl->crypt_counter_local++, (const uint8_t *)session->connect_info.regist_key, auth_enc, CHIAKI_RPCRYPT_KEY_SIZE);
if(err != CHIAKI_ERR_SUCCESS)
goto error;
char auth_b64[CHIAKI_RPCRYPT_KEY_SIZE*2];

@ -245,7 +245,7 @@ static void *discovery_thread_func(void *user)
while(1)
{
ChiakiErrorCode err = chiaki_stop_pipe_select_single(&thread->stop_pipe, discovery->socket, UINT64_MAX);
ChiakiErrorCode err = chiaki_stop_pipe_select_single(&thread->stop_pipe, discovery->socket, false, UINT64_MAX);
if(err == CHIAKI_ERR_CANCELED)
break;
if(err != CHIAKI_ERR_SUCCESS)

@ -157,7 +157,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_recv_http_header(int sock, char *buf, size_
{
if(stop_pipe)
{
ChiakiErrorCode err = chiaki_stop_pipe_select_single(stop_pipe, sock, timeout_ms);
ChiakiErrorCode err = chiaki_stop_pipe_select_single(stop_pipe, sock, false, timeout_ms);
if(err != CHIAKI_ERR_SUCCESS)
return err;
}

@ -349,7 +349,7 @@ static ChiakiErrorCode regist_search(ChiakiRegist *regist, struct addrinfo *addr
if(now_ms > timeout_abs_ms)
err = CHIAKI_ERR_TIMEOUT;
else
err = chiaki_stop_pipe_select_single(&regist->stop_pipe, sock, timeout_abs_ms - now_ms);
err = chiaki_stop_pipe_select_single(&regist->stop_pipe, sock, false, timeout_abs_ms - now_ms);
if(err != CHIAKI_ERR_SUCCESS)
{
if(err == CHIAKI_ERR_TIMEOUT)
@ -551,7 +551,7 @@ static ChiakiErrorCode regist_recv_response(ChiakiRegist *regist, ChiakiRegister
while(buf_filled_size < content_size + header_size)
{
err = chiaki_stop_pipe_select_single(&regist->stop_pipe, sock, REGIST_REPONSE_TIMEOUT_MS);
err = chiaki_stop_pipe_select_single(&regist->stop_pipe, sock, false, REGIST_REPONSE_TIMEOUT_MS);
if(err != CHIAKI_ERR_SUCCESS)
{
if(err == CHIAKI_ERR_TIMEOUT)

@ -628,29 +628,36 @@ static bool session_thread_request_session(ChiakiSession *session, ChiakiRpVersi
free(sa);
continue;
}
r = connect(session_sock, sa, ai->ai_addrlen);
if(r < 0)
ChiakiErrorCode err = chiaki_socket_set_nonblock(session_sock, true);
if(err != CHIAKI_ERR_SUCCESS)
CHIAKI_LOGE(session->log, "Failed to set session socket to non-blocking: %s", chiaki_error_string(err));
chiaki_mutex_unlock(&session->state_mutex);
err = chiaki_stop_pipe_connect(&session->stop_pipe, session_sock, sa, ai->ai_addrlen);
chiaki_mutex_lock(&session->state_mutex);
if(err == CHIAKI_ERR_CANCELED)
{
#ifdef _WIN32
int err = WSAGetLastError();
CHIAKI_LOGE(session->log, "Session request connect failed: %u", err);
if(err == WSAECONNREFUSED)
CHIAKI_LOGI(session->log, "Session stopped while connecting for session request");
session->quit_reason = CHIAKI_QUIT_REASON_STOPPED;
CHIAKI_SOCKET_CLOSE(session_sock);
session_sock = -1;
free(sa);
break;
}
else if(err != CHIAKI_ERR_SUCCESS)
{
CHIAKI_LOGE(session->log, "Session request connect failed: %s", chiaki_error_string(err));
if(err == CHIAKI_ERR_CONNECTION_REFUSED)
session->quit_reason = CHIAKI_QUIT_REASON_SESSION_REQUEST_CONNECTION_REFUSED;
else
session->quit_reason = CHIAKI_QUIT_REASON_NONE;
#else
int errsv = errno;
CHIAKI_LOGE(session->log, "Session request connect failed: %s", strerror(errsv));
if(errsv == ECONNREFUSED)
session->quit_reason = CHIAKI_QUIT_REASON_SESSION_REQUEST_CONNECTION_REFUSED;
else
session->quit_reason = CHIAKI_QUIT_REASON_NONE;
#endif
CHIAKI_SOCKET_CLOSE(session_sock);
session_sock = -1;
free(sa);
continue;
}
free(sa);
session->connect_info.host_addrinfo_selected = ai;

36
lib/src/sock.c Normal file

@ -0,0 +1,36 @@
/*
* This file is part of Chiaki.
*
* Chiaki is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Chiaki is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chiaki. If not, see <https://www.gnu.org/licenses/>.
*/
#include <chiaki/sock.h>
#include <fcntl.h>
CHIAKI_EXPORT ChiakiErrorCode chiaki_socket_set_nonblock(chiaki_socket_t sock, bool nonblock)
{
#ifdef _WIN32
u_long nbio = nonblock ? 1 : 0;
if(ioctlsocket(sock, FIONBIO, &nbio) != NO_ERROR)
return CHIAKI_ERR_UNKNOWN;
#else
int flags = fcntl(sock, F_GETFL, 0);
if(flags == -1)
return CHIAKI_ERR_UNKNOWN;
flags = nonblock ? (flags | O_NONBLOCK) : (flags & ~O_NONBLOCK);
if(fcntl(sock, F_SETFL, flags) == -1)
return CHIAKI_ERR_UNKNOWN;
#endif
return CHIAKI_ERR_SUCCESS;
}

@ -16,11 +16,12 @@
*/
#include <chiaki/stoppipe.h>
#include <chiaki/sock.h>
#include <fcntl.h>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <unistd.h>
#include <sys/socket.h>
@ -69,7 +70,7 @@ CHIAKI_EXPORT void chiaki_stop_pipe_stop(ChiakiStopPipe *stop_pipe)
#endif
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, uint64_t timeout_ms)
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, bool write, uint64_t timeout_ms)
{
#ifdef _WIN32
WSAEVENT events[2];
@ -82,7 +83,7 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
events[1] = WSACreateEvent();
if(events[1] == WSA_INVALID_EVENT)
return CHIAKI_ERR_UNKNOWN;
WSAEventSelect(fd, events[1], FD_READ);
WSAEventSelect(fd, events[1], write ? FD_WRITE : FD_READ);
}
DWORD r = WSAWaitForMultipleEvents(events_count, events, FALSE, timeout_ms == UINT64_MAX ? WSA_INFINITE : (DWORD)timeout_ms, FALSE);
@ -102,14 +103,17 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
return CHIAKI_ERR_UNKNOWN;
}
#else
fd_set fds;
FD_ZERO(&fds);
FD_SET(stop_pipe->fds[0], &fds);
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(stop_pipe->fds[0], &rfds);
fd_set wfds;
FD_ZERO(&wfds);
int nfds = stop_pipe->fds[0];
if(fd >= 0)
if(!CHIAKI_SOCKET_IS_INVALID(fd))
{
FD_SET(fd, &fds);
FD_SET(fd, write ? &wfds : &rfds);
if(fd > nfds)
nfds = fd;
}
@ -124,20 +128,96 @@ CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_select_single(ChiakiStopPipe *sto
timeout = &timeout_s;
}
int r = select(nfds, &fds, NULL, NULL, timeout);
int r = select(nfds, &rfds, write ? &wfds : NULL, NULL, timeout);
if(r < 0)
return CHIAKI_ERR_UNKNOWN;
if(FD_ISSET(stop_pipe->fds[0], &fds))
if(FD_ISSET(stop_pipe->fds[0], &rfds))
return CHIAKI_ERR_CANCELED;
if(fd >= 0 && FD_ISSET(fd, &fds))
if(!CHIAKI_SOCKET_IS_INVALID(fd) && FD_ISSET(fd, write ? &wfds : &rfds))
return CHIAKI_ERR_SUCCESS;
return CHIAKI_ERR_TIMEOUT;
#endif
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_connect(ChiakiStopPipe *stop_pipe, chiaki_socket_t fd, struct sockaddr *addr, size_t addrlen)
{
int r = connect(fd, addr, (socklen_t)addrlen);
if(r >= 0)
return CHIAKI_ERR_SUCCESS;
if(CHIAKI_SOCKET_EINPROGRESS)
{
ChiakiErrorCode err = chiaki_stop_pipe_select_single(stop_pipe, fd, true, UINT64_MAX);
if(err != CHIAKI_ERR_SUCCESS)
return err;
}
else
{
#ifdef _WIN32
int err = WSAGetLastError();
if(err == WSAECONNREFUSED)
return CHIAKI_ERR_CONNECTION_REFUSED;
else
return CHIAKI_ERR_NETWORK;
#else
if(errno == ECONNREFUSED)
return CHIAKI_ERR_CONNECTION_REFUSED;
else
return CHIAKI_ERR_NETWORK;
#endif
}
struct sockaddr peer;
socklen_t peerlen = sizeof(peer);
if(getpeername(fd, &peer, &peerlen) == 0)
return CHIAKI_ERR_SUCCESS;
if(errno != ENOTCONN)
return CHIAKI_ERR_UNKNOWN;
#ifdef _WIN32
DWORD sockerr;
#else
int sockerr;
#endif
socklen_t sockerr_sz = sizeof(sockerr);
if(getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerr_sz) < 0)
return CHIAKI_ERR_UNKNOWN;
#ifdef _WIN32
switch(sockerr)
{
case WSAETIMEDOUT:
return CHIAKI_ERR_TIMEOUT;
case WSAECONNREFUSED:
return CHIAKI_ERR_CONNECTION_REFUSED;
case WSAEHOSTDOWN:
return CHIAKI_ERR_HOST_DOWN;
case WSAEHOSTUNREACH:
return CHIAKI_ERR_HOST_UNREACH;
default:
return CHIAKI_ERR_UNKNOWN;
}
#else
switch(sockerr)
{
case ETIMEDOUT:
return CHIAKI_ERR_TIMEOUT;
case ECONNREFUSED:
return CHIAKI_ERR_CONNECTION_REFUSED;
case EHOSTDOWN:
return CHIAKI_ERR_HOST_DOWN;
case EHOSTUNREACH:
return CHIAKI_ERR_HOST_UNREACH;
default:
return CHIAKI_ERR_UNKNOWN;
}
#endif
}
CHIAKI_EXPORT ChiakiErrorCode chiaki_stop_pipe_reset(ChiakiStopPipe *stop_pipe)
{
#ifdef _WIN32

@ -757,7 +757,7 @@ beach:
static ChiakiErrorCode takion_recv(ChiakiTakion *takion, uint8_t *buf, size_t *buf_size, uint64_t timeout_ms)
{
ChiakiErrorCode err = chiaki_stop_pipe_select_single(&takion->stop_pipe, takion->sock, timeout_ms);
ChiakiErrorCode err = chiaki_stop_pipe_select_single(&takion->stop_pipe, takion->sock, false, timeout_ms);
if(err == CHIAKI_ERR_TIMEOUT || err == CHIAKI_ERR_CANCELED)
return err;
if(err != CHIAKI_ERR_SUCCESS)

@ -18,7 +18,7 @@
#ifndef CHIAKI_UTILS_H
#define CHIAKI_UTILS_H
#include <chiaki/common.h>
#include <chiaki/sock.h>
#include <chiaki/log.h>
#ifdef _WIN32
#include <ws2tcpip.h>