Networking: support timeout on Linux

This commit is contained in:
李通洲
2023-09-22 16:06:04 +08:00
parent db5619541a
commit cc6cdb96fb
2 changed files with 42 additions and 5 deletions
+4 -3
View File
@@ -77,7 +77,8 @@ bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, con
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
{
#ifdef FF_HAVE_THREADS
ffThreadJoin(state->thread);
if (!ffThreadJoin(state->thread, timeout))
return false;
#endif
if(state->sockfd == -1)
return false;
@@ -85,8 +86,8 @@ bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, ui
if(timeout > 0)
{
struct timeval timev;
timev.tv_sec = 0;
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
timev.tv_sec = timeout / 1000;
timev.tv_usec = (__typeof__(timev.tv_usec)) ((timeout % 1000) * 1000); //milliseconds to microseconds
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
}
+38 -2
View File
@@ -10,6 +10,7 @@
#include <handleapi.h>
#include <synchapi.h>
#include <process.h>
#include <processthreadsapi.h>
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
typedef SRWLOCK FFThreadMutex;
typedef HANDLE FFThreadType;
@@ -21,9 +22,23 @@
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
#define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static __stdcall unsigned fn ## ThreadMain () { fn(); return 0; }
static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); }
static inline void ffThreadJoin(FFThreadType thread) { WaitForSingleObject(thread, 0xffffffff /*INFINITE*/); }
static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout)
{
if (WaitForSingleObject(thread, timeout == 0 ? (DWORD) -1 : timeout) != 0 /*WAIT_OBJECT_0*/)
{
TerminateThread(thread, (DWORD) -1);
CloseHandle(thread);
return false;
}
CloseHandle(thread);
return true;
}
#else
#include <pthread.h>
#include <signal.h>
#if __has_include(<pthread_np.h>)
#include <pthread_np.h>
#endif
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
typedef pthread_mutex_t FFThreadMutex;
typedef pthread_t FFThreadType;
@@ -37,7 +52,28 @@
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
#define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) static void* fn ## ThreadMain () { fn(); return NULL; }
static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); }
static inline void ffThreadJoin(FFThreadType thread) { pthread_join(thread, NULL); }
static inline bool ffThreadJoin(FFThreadType thread, FF_MAYBE_UNUSED uint32_t timeout)
{
#if (defined(__linux__) && !defined(__ANDROID__)) || __has_include(<pthread_np.h>)
if (timeout > 0)
{
struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts) == 0)
{
ts.tv_sec += ts.tv_sec / 1000;
ts.tv_nsec += (ts.tv_nsec % 1000) * 1000000;
if (pthread_timedjoin_np(thread, NULL, &ts) != 0)
{
pthread_kill(thread, SIGTERM);
return false;
}
return true;
}
}
#endif
pthread_join(thread, NULL);
return true;
}
#endif
#else //FF_HAVE_THREADS
#define FF_THREAD_MUTEX_INITIALIZER 0