Mercurial > hg > nginx-quic
view src/event/ngx_event_connectex.c @ 7247:b329c0ab1a48
Configure: restored "no-threads" in OpenSSL builds.
This was previously used, but was incorrectly removed in 83d54192e97b
while removing old threads remnants. Instead of using it conditionally
when threads are not used, we now set in unconditionally, as even with
thread pools enabled we never call OpenSSL functions in threads.
This fixes resulting binary when using --with-openssl with OpenSSL 1.1.0+
and without -lpthread linked (notably on FreeBSD without PCRE).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 22 Mar 2018 15:56:07 +0300 |
parents | d620f497c50f |
children | 1c3b78d7cdc9 |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #include <ngx_config.h> #include <ngx_core.h> #include <ngx_event.h> #define NGX_MAX_PENDING_CONN 10 static CRITICAL_SECTION connect_lock; static int nconnects; static ngx_connection_t pending_connects[NGX_MAX_PENDING_CONN]; static HANDLE pending_connect_event; __declspec(thread) int nevents = 0; __declspec(thread) WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS + 1]; __declspec(thread) ngx_connection_t *conn[WSA_MAXIMUM_WAIT_EVENTS + 1]; int ngx_iocp_wait_connect(ngx_connection_t *c) { for ( ;; ) { EnterCriticalSection(&connect_lock); if (nconnects < NGX_MAX_PENDING_CONN) { pending_connects[--nconnects] = c; LeaveCriticalSection(&connect_lock); if (SetEvent(pending_connect_event) == 0) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "SetEvent() failed"); return NGX_ERROR; break; } LeaveCriticalSection(&connect_lock); ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "max number of pending connect()s is %d", NGX_MAX_PENDING_CONN); msleep(100); } if (!started) { if (ngx_iocp_new_thread(1) == NGX_ERROR) { return NGX_ERROR; } started = 1; } return NGX_OK; } int ngx_iocp_new_thread(int main) { u_int id; if (main) { pending_connect_event = CreateEvent(NULL, 0, 1, NULL); if (pending_connect_event == INVALID_HANDLE_VALUE) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CreateThread() failed"); return NGX_ERROR; } } if (CreateThread(NULL, 0, ngx_iocp_wait_events, main, 0, &id) == INVALID_HANDLE_VALUE) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "CreateThread() failed"); return NGX_ERROR; } SetEvent(event) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, "SetEvent() failed"); return NGX_ERROR; } return NGX_OK; } int ngx_iocp_new_connect() { EnterCriticalSection(&connect_lock); c = pending_connects[--nconnects]; LeaveCriticalSection(&connect_lock); conn[nevents] = c; events[nevents] = WSACreateEvent(); if (events[nevents] == INVALID_HANDLE_VALUE) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, "WSACreateEvent() failed"); return NGX_ERROR; } if (WSAEventSelect(c->fd, events[nevents], FD_CONNECT) == -1) ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, "WSAEventSelect() failed"); return NGX_ERROR; } nevents++; return NGX_OK; } void ngx_iocp_wait_events(int main) { WSANETWORKEVENTS ne; nevents = 1; events[0] = pending_connect_event; conn[0] = NULL; for ( ;; ) { offset = (nevents == WSA_MAXIMUM_WAIT_EVENTS + 1) ? 1: 0; timeout = (nevents == 1 && !first) ? 60000: INFINITE; n = WSAWaitForMultipleEvents(nevents - offset, events[offset], 0, timeout, 0); if (n == WAIT_FAILED) { ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, "WSAWaitForMultipleEvents() failed"); continue; } if (n == WAIT_TIMEOUT) { if (nevents == 2 && !main) { ExitThread(0); } ngx_log_error(NGX_LOG_ALERT, log, 0, "WSAWaitForMultipleEvents() " "returned unexpected WAIT_TIMEOUT"); continue; } n -= WSA_WAIT_EVENT_0; if (events[n] == NULL) { /* the pending_connect_event */ if (nevents == WSA_MAXIMUM_WAIT_EVENTS) { ngx_iocp_new_thread(0); } else { ngx_iocp_new_connect(); } continue; } if (WSAEnumNetworkEvents(c[n].fd, events[n], &ne) == -1) { ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, "WSAEnumNetworkEvents() failed"); continue; } if (ne.lNetworkEvents & FD_CONNECT) { conn[n].write->ovlp.error = ne.iErrorCode[FD_CONNECT_BIT]; if (PostQueuedCompletionStatus(iocp, 0, NGX_IOCP_CONNECT, &conn[n].write->ovlp) == 0) { ngx_log_error(NGX_LOG_ALERT, log, ngx_socket_errno, "PostQueuedCompletionStatus() failed"); continue; } if (n < nevents) { conn[n] = conn[nevents]; events[n] = events[nevents]; } nevents--; continue; } if (ne.lNetworkEvents & FD_ACCEPT) { /* CHECK ERROR ??? */ ngx_event_post_acceptex(conn[n].listening, 1); continue; } ngx_log_error(NGX_LOG_ALERT, c[n].log, 0, "WSAWaitForMultipleEvents() " "returned unexpected network event %ul", ne.lNetworkEvents); } }