• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2016 Tino Reichardt
3  * All rights reserved.
4  *
5  * This source code is licensed under both the BSD-style license (found in the
6  * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7  * in the COPYING file in the root directory of this source tree).
8  *
9  * You can contact the author at:
10  * - zstdmt source repository: https://github.com/mcmilk/zstdmt
11  */
12 
13 /**
14  * This file will hold wrapper for systems, which do not support pthreads
15  */
16 
17 
18  /* ===  Build Macro  === */
19 
20  #ifndef POOL_MT   // can be defined on command line
21  #  define POOL_MT 1
22  #endif
23 
24 
25 /* create fake symbol to avoid empty translation unit warning */
26 int g_ZSTD_threading_useles_symbol;
27 
28 #if POOL_MT && defined(_WIN32)
29 
30 /**
31  * Windows minimalist Pthread Wrapper
32  */
33 
34 
35 /* ===  Dependencies  === */
36 #include <process.h>
37 #include <errno.h>
38 #include "threading.h"
39 
40 
41 /* ===  Implementation  === */
42 
worker(void * arg)43 static unsigned __stdcall worker(void *arg)
44 {
45     ZSTD_pthread_t* const thread = (ZSTD_pthread_t*) arg;
46     thread->arg = thread->start_routine(thread->arg);
47     return 0;
48 }
49 
ZSTD_pthread_create(ZSTD_pthread_t * thread,const void * unused,void * (* start_routine)(void *),void * arg)50 int ZSTD_pthread_create(ZSTD_pthread_t* thread, const void* unused,
51             void* (*start_routine) (void*), void* arg)
52 {
53     (void)unused;
54     thread->arg = arg;
55     thread->start_routine = start_routine;
56     thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
57 
58     if (!thread->handle)
59         return errno;
60     else
61         return 0;
62 }
63 
ZSTD_pthread_join(ZSTD_pthread_t thread,void ** value_ptr)64 int ZSTD_pthread_join(ZSTD_pthread_t thread, void **value_ptr)
65 {
66     DWORD result;
67 
68     if (!thread.handle) return 0;
69 
70     result = WaitForSingleObject(thread.handle, INFINITE);
71     switch (result) {
72     case WAIT_OBJECT_0:
73         if (value_ptr) *value_ptr = thread.arg;
74         return 0;
75     case WAIT_ABANDONED:
76         return EINVAL;
77     default:
78         return (int)GetLastError();
79     }
80 }
81 
82 #endif   /* POOL_MT */
83