|
@@ -803,6 +803,87 @@ stat(const char *name, struct stat *st)
|
|
|
#endif /* defined(_WIN32_WCE) */
|
|
|
|
|
|
|
|
|
+#if defined(__GNUC__)
|
|
|
+/* Show no warning in case system functions are not used. */
|
|
|
+#pragma GCC diagnostic push
|
|
|
+#pragma GCC diagnostic ignored "-Wunused-function"
|
|
|
+#endif
|
|
|
+#if defined(__clang__)
|
|
|
+/* Show no warning in case system functions are not used. */
|
|
|
+#pragma clang diagnostic push
|
|
|
+#pragma clang diagnostic ignored "-Wunused-function"
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+/* Get a unique thread ID as unsigned long, independent from the data type
|
|
|
+ * of thread IDs defined by the operating system API.
|
|
|
+ * If two calls to mg_current_thread_id return the same value, they calls
|
|
|
+ * are done from the same thread. If they return different values, they are
|
|
|
+ * done from different threads. (Provided this function is used in the same
|
|
|
+ * process context and threads are not repeatedly created and deleted, but
|
|
|
+ * CivetWeb does not do that).
|
|
|
+ * This function must match the signature required for SSL id callbacks:
|
|
|
+ * CRYPTO_set_id_callback
|
|
|
+ */
|
|
|
+static unsigned long
|
|
|
+mg_current_thread_id(void)
|
|
|
+{
|
|
|
+#ifdef _WIN32
|
|
|
+ return GetCurrentThreadId();
|
|
|
+#else
|
|
|
+
|
|
|
+#ifdef __clang__
|
|
|
+#pragma clang diagnostic push
|
|
|
+#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
|
+/* For every compiler, either "sizeof(pthread_t) > sizeof(unsigned long)"
|
|
|
+ * or not, so one of the two conditions will be unreachable by construction.
|
|
|
+ * Unfortunately the C standard does not define a way to check this at
|
|
|
+ * compile time, since the #if preprocessor conditions can not use the sizeof
|
|
|
+ * operator as an argument. */
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (sizeof(pthread_t) > sizeof(unsigned long)) {
|
|
|
+ /* This is the problematic case for CRYPTO_set_id_callback:
|
|
|
+ * The OS pthread_t can not be cast to unsigned long. */
|
|
|
+ struct mg_workerTLS *tls =
|
|
|
+ (struct mg_workerTLS *)pthread_getspecific(sTlsKey);
|
|
|
+ if (tls == NULL) {
|
|
|
+ /* SSL called from an unknown thread: Create some thread index.
|
|
|
+ */
|
|
|
+ tls = (struct mg_workerTLS *)mg_malloc(sizeof(struct mg_workerTLS));
|
|
|
+ tls->is_master = -2; /* -2 means "3rd party thread" */
|
|
|
+ tls->thread_idx = (unsigned)mg_atomic_inc(&thread_idx_max);
|
|
|
+ pthread_setspecific(sTlsKey, tls);
|
|
|
+ }
|
|
|
+ return tls->thread_idx;
|
|
|
+ } else {
|
|
|
+ /* pthread_t may be any data type, so a simple cast to unsigned long
|
|
|
+ * can rise a warning/error, depending on the platform.
|
|
|
+ * Here memcpy is used as an anything-to-anything cast. */
|
|
|
+ unsigned long ret = 0;
|
|
|
+ pthread_t t = pthread_self();
|
|
|
+ memcpy(&ret, &t, sizeof(pthread_t));
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef __clang__
|
|
|
+#pragma clang diagnostic pop
|
|
|
+#endif
|
|
|
+
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+#if defined(__GNUC__)
|
|
|
+/* Show no warning in case system functions are not used. */
|
|
|
+#pragma GCC diagnostic pop
|
|
|
+#endif
|
|
|
+#if defined(__clang__)
|
|
|
+/* Show no warning in case system functions are not used. */
|
|
|
+#pragma clang diagnostic pop
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
#if !defined(DEBUG_TRACE)
|
|
|
#if defined(DEBUG)
|
|
|
static void DEBUG_TRACE_FUNC(const char *func,
|
|
@@ -819,22 +900,17 @@ DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...)
|
|
|
static uint64_t nslast;
|
|
|
|
|
|
/* Get some operating system independent thread id */
|
|
|
- uint64_t thread_as_i64;
|
|
|
- pthread_t t = pthread_self();
|
|
|
- memcpy(&thread_as_i64,
|
|
|
- &t,
|
|
|
- ((sizeof(t) < sizeof(thread_as_i64)) ? sizeof(t)
|
|
|
- : sizeof(thread_as_i64)));
|
|
|
+ unsigned long thread_id = mg_current_thread_id();
|
|
|
|
|
|
clock_gettime(CLOCK_REALTIME, &tsnow);
|
|
|
nsnow = (((uint64_t)tsnow.tv_sec) * 1000000000) + (uint64_t)tsnow.tv_nsec;
|
|
|
|
|
|
flockfile(stdout);
|
|
|
- printf("*** %lu.%09lu %12" INT64_FMT " %" INT64_FMT " %s:%u: ",
|
|
|
+ printf("*** %lu.%09lu %12" INT64_FMT " %lu %s:%u: ",
|
|
|
(unsigned long)tsnow.tv_sec,
|
|
|
(unsigned long)tsnow.tv_nsec,
|
|
|
nsnow - nslast,
|
|
|
- thread_as_i64,
|
|
|
+ thread_id,
|
|
|
func,
|
|
|
line);
|
|
|
va_start(args, fmt);
|
|
@@ -11501,56 +11577,6 @@ tls_dtor(void *key)
|
|
|
|
|
|
#if !defined(NO_SSL)
|
|
|
|
|
|
-/* Must be set if sizeof(pthread_t) > sizeof(unsigned long) */
|
|
|
-static unsigned long
|
|
|
-ssl_id_callback(void)
|
|
|
-{
|
|
|
-#ifdef _WIN32
|
|
|
- return GetCurrentThreadId();
|
|
|
-#else
|
|
|
-
|
|
|
-#ifdef __clang__
|
|
|
-#pragma clang diagnostic push
|
|
|
-#pragma clang diagnostic ignored "-Wunreachable-code"
|
|
|
-/* For every compiler, either "sizeof(pthread_t) > sizeof(unsigned long)"
|
|
|
- * or not, so one of the two conditions will be unreachable by construction.
|
|
|
- * Unfortunately the C standard does not define a way to check this at
|
|
|
- * compile time, since the #if preprocessor conditions can not use the sizeof
|
|
|
- * operator as an argument. */
|
|
|
-#endif
|
|
|
-
|
|
|
- if (sizeof(pthread_t) > sizeof(unsigned long)) {
|
|
|
- /* This is the problematic case for CRYPTO_set_id_callback:
|
|
|
- * The OS pthread_t can not be cast to unsigned long. */
|
|
|
- struct mg_workerTLS *tls =
|
|
|
- (struct mg_workerTLS *)pthread_getspecific(sTlsKey);
|
|
|
- if (tls == NULL) {
|
|
|
- /* SSL called from an unknown thread: Create some thread index.
|
|
|
- */
|
|
|
- tls = (struct mg_workerTLS *)mg_malloc(sizeof(struct mg_workerTLS));
|
|
|
- tls->is_master = -2; /* -2 means "3rd party thread" */
|
|
|
- tls->thread_idx = (unsigned)mg_atomic_inc(&thread_idx_max);
|
|
|
- pthread_setspecific(sTlsKey, tls);
|
|
|
- }
|
|
|
- return tls->thread_idx;
|
|
|
- } else {
|
|
|
- /* pthread_t may be any data type, so a simple cast to unsigned long
|
|
|
- * can rise a warning/error, depending on the platform.
|
|
|
- * Here memcpy is used as an anything-to-anything cast. */
|
|
|
- unsigned long ret = 0;
|
|
|
- pthread_t t = pthread_self();
|
|
|
- memcpy(&ret, &t, sizeof(pthread_t));
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
-#ifdef __clang__
|
|
|
-#pragma clang diagnostic pop
|
|
|
-#endif
|
|
|
-
|
|
|
-#endif
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
static int ssl_use_pem_file(struct mg_context *ctx, const char *pem);
|
|
|
static const char *ssl_error(void);
|
|
|
|
|
@@ -11925,7 +11951,7 @@ initialize_ssl(struct mg_context *ctx)
|
|
|
}
|
|
|
|
|
|
CRYPTO_set_locking_callback(&ssl_locking_callback);
|
|
|
- CRYPTO_set_id_callback(&ssl_id_callback);
|
|
|
+ CRYPTO_set_id_callback(&mg_current_thread_id);
|
|
|
|
|
|
return 1;
|
|
|
}
|