Disable native socketpair by default, fix multithreaded win32 example

This commit is contained in:
cpq 2021-01-21 09:12:49 +00:00
parent be62ac9c14
commit 51bc5f70c5
3 changed files with 25 additions and 19 deletions

View File

@ -31,20 +31,11 @@ struct response {
#define SLEEP_TIME 3 // Seconds to sleep to simulate calculation #define SLEEP_TIME 3 // Seconds to sleep to simulate calculation
#endif #endif
static void thread_function(void *param) {
int sock = (long) param; // Grab our blocking socket
struct response r = {strdup("hello"), 5}; // Create response
sleep(SLEEP_TIME); // Simulate long execution
send(sock, (void *) &r, sizeof(r), 0); // Send to request handler
close(sock); // Done, close socket, end thread
}
static void start_thread(void (*f)(void *), void *p) { static void start_thread(void (*f)(void *), void *p) {
#ifdef WINCE #ifdef _WIN32
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) f, p, 0, NULL);
#elif defined(_WIN32)
_beginthread((void(__cdecl *)(void *)) f, 0, p); _beginthread((void(__cdecl *)(void *)) f, 0, p);
#else #else
#define closesocket(x) close(x)
#include <pthread.h> #include <pthread.h>
pthread_t thread_id = (pthread_t) 0; pthread_t thread_id = (pthread_t) 0;
pthread_attr_t attr; pthread_attr_t attr;
@ -55,6 +46,15 @@ static void start_thread(void (*f)(void *), void *p) {
#endif #endif
} }
static void thread_function(void *param) {
int sock = (long) param; // Grab our blocking socket
struct response r = {strdup("hello\n"), 6}; // Create response
mg_usleep(SLEEP_TIME * 1000000); // Simulate long execution
LOG(LL_INFO, ("got sock %d", sock)); // For debugging
send(sock, (void *) &r, sizeof(r), 0); // Send to request handler
closesocket(sock); // Done, close socket, end thread
}
// HTTP request callback // HTTP request callback
static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
@ -70,7 +70,7 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
"Content-Length: 3\r\n\r\n" // Set to allow keep-alive "Content-Length: 3\r\n\r\n" // Set to allow keep-alive
"hi\n"); "hi\n");
} else { } else {
int blocking, non_blocking; int blocking = -1, non_blocking = -1;
mg_socketpair(&blocking, &non_blocking); // Create connected pair mg_socketpair(&blocking, &non_blocking); // Create connected pair
// Pass blocking socket to the thread_function. // Pass blocking socket to the thread_function.
@ -90,7 +90,7 @@ static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
mg_printf(c, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n%.*s", mg_printf(c, "HTTP/1.0 200 OK\r\nContent-Length: %d\r\n\r\n%.*s",
response.len, response.len, response.data); response.len, response.len, response.data);
free(response.data); // We can free produced data now free(response.data); // We can free produced data now
close(sock); // And close our end of the socket pair closesocket(sock); // And close our end of the socket pair
c->fn_data = NULL; c->fn_data = NULL;
} }
} }

View File

@ -2849,17 +2849,20 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
#if MG_ENABLE_SOCKETPAIR #if MG_ENABLE_SOCKETPAIR
bool mg_socketpair(int *s1, int *s2) { bool mg_socketpair(int *s1, int *s2) {
#if MG_ARCH == MG_ARCH_UNIX #ifdef MG_ENABLE_NATIVE_SOCKETPAIR
// For some reason, native socketpair() call fails on Macos
// Enable this codepath only when MG_ENABLE_NATIVE_SOCKETPAIR is defined
int sp[2], ret = 0; int sp[2], ret = 0;
if (socketpair(AF_INET, SOCK_DGRAM, 0, sp) == 0) { if (socketpair(AF_INET, SOCK_DGRAM, IPPROTO_UDP, sp) == 0) {
*s1 = sp[0], *s2 = sp[1], ret = 1; *s1 = sp[0], *s2 = sp[1], ret = 1;
} }
LOG(LL_INFO, ("errno %d", errno));
return ret; return ret;
#else #else
union usa sa, sa2; union usa sa, sa2;
SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET}; SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET};
socklen_t len = sizeof(sa.sin); socklen_t len = sizeof(sa.sin);
int ret = 0, res[2] = {-1, -1}; int ret = 0;
(void) memset(&sa, 0, sizeof(sa)); (void) memset(&sa, 0, sizeof(sa));
sa.sin.sin_family = AF_INET; sa.sin.sin_family = AF_INET;

View File

@ -400,17 +400,20 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) {
#if MG_ENABLE_SOCKETPAIR #if MG_ENABLE_SOCKETPAIR
bool mg_socketpair(int *s1, int *s2) { bool mg_socketpair(int *s1, int *s2) {
#if MG_ARCH == MG_ARCH_UNIX #ifdef MG_ENABLE_NATIVE_SOCKETPAIR
// For some reason, native socketpair() call fails on Macos
// Enable this codepath only when MG_ENABLE_NATIVE_SOCKETPAIR is defined
int sp[2], ret = 0; int sp[2], ret = 0;
if (socketpair(AF_INET, SOCK_DGRAM, 0, sp) == 0) { if (socketpair(AF_INET, SOCK_DGRAM, IPPROTO_UDP, sp) == 0) {
*s1 = sp[0], *s2 = sp[1], ret = 1; *s1 = sp[0], *s2 = sp[1], ret = 1;
} }
LOG(LL_INFO, ("errno %d", errno));
return ret; return ret;
#else #else
union usa sa, sa2; union usa sa, sa2;
SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET}; SOCKET sp[2] = {INVALID_SOCKET, INVALID_SOCKET};
socklen_t len = sizeof(sa.sin); socklen_t len = sizeof(sa.sin);
int ret = 0, res[2] = {-1, -1}; int ret = 0;
(void) memset(&sa, 0, sizeof(sa)); (void) memset(&sa, 0, sizeof(sa));
sa.sin.sin_family = AF_INET; sa.sin.sin_family = AF_INET;