Line data Source code
1 : /*
2 : Copyright (c) 2007-2016 Contributors as noted in the AUTHORS file
3 :
4 : This file is part of libzmq, the ZeroMQ core engine in C++.
5 :
6 : libzmq is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU Lesser General Public License (LGPL) as published
8 : by the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : As a special exception, the Contributors give you permission to link
12 : this library with independent modules to produce an executable,
13 : regardless of the license terms of these independent modules, and to
14 : copy and distribute the resulting executable under terms of your choice,
15 : provided that you also meet, for each linked independent module, the
16 : terms and conditions of the license of that module. An independent
17 : module is a module which is not derived from or based on this library.
18 : If you modify this library, you must extend this exception to your
19 : version of the library.
20 :
21 : libzmq is distributed in the hope that it will be useful, but WITHOUT
22 : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
24 : License for more details.
25 :
26 : You should have received a copy of the GNU Lesser General Public License
27 : along with this program. If not, see <http://www.gnu.org/licenses/>.
28 : */
29 :
30 : #include "precompiled.hpp"
31 : #include "thread.hpp"
32 : #include "err.hpp"
33 : #include "platform.hpp"
34 :
35 : #ifdef ZMQ_HAVE_WINDOWS
36 :
37 : extern "C"
38 : {
39 : #if defined _WIN32_WCE
40 : static DWORD thread_routine (LPVOID arg_)
41 : #else
42 : static unsigned int __stdcall thread_routine (void *arg_)
43 : #endif
44 : {
45 : zmq::thread_t *self = (zmq::thread_t*) arg_;
46 : self->tfn (self->arg);
47 : return 0;
48 : }
49 : }
50 :
51 : void zmq::thread_t::start (thread_fn *tfn_, void *arg_)
52 : {
53 : tfn = tfn_;
54 : arg = arg_;
55 : #if defined _WIN32_WCE
56 : descriptor = (HANDLE) CreateThread (NULL, 0,
57 : &::thread_routine, this, 0 , NULL);
58 : #else
59 : descriptor = (HANDLE) _beginthreadex (NULL, 0,
60 : &::thread_routine, this, 0 , NULL);
61 : #endif
62 : win_assert (descriptor != NULL);
63 : }
64 :
65 : void zmq::thread_t::stop ()
66 : {
67 : DWORD rc = WaitForSingleObject (descriptor, INFINITE);
68 : win_assert (rc != WAIT_FAILED);
69 : BOOL rc2 = CloseHandle (descriptor);
70 : win_assert (rc2 != 0);
71 : }
72 :
73 : void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_)
74 : {
75 : // not implemented
76 : }
77 :
78 : #else
79 :
80 : #include <signal.h>
81 : #include <unistd.h>
82 :
83 : extern "C"
84 : {
85 4469 : static void *thread_routine (void *arg_)
86 : {
87 : #if !defined ZMQ_HAVE_OPENVMS && !defined ZMQ_HAVE_ANDROID
88 : // Following code will guarantee more predictable latencies as it'll
89 : // disallow any signal handling in the I/O thread.
90 : sigset_t signal_set;
91 4469 : int rc = sigfillset (&signal_set);
92 4468 : errno_assert (rc == 0);
93 4468 : rc = pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
94 4470 : posix_assert (rc);
95 : #endif
96 :
97 4470 : zmq::thread_t *self = (zmq::thread_t*) arg_;
98 4470 : self->tfn (self->arg);
99 4470 : return NULL;
100 : }
101 : }
102 :
103 4470 : void zmq::thread_t::start (thread_fn *tfn_, void *arg_)
104 : {
105 4470 : tfn = tfn_;
106 4470 : arg = arg_;
107 4470 : int rc = pthread_create (&descriptor, NULL, thread_routine, this);
108 4470 : posix_assert (rc);
109 4470 : }
110 :
111 4470 : void zmq::thread_t::stop ()
112 : {
113 4470 : int rc = pthread_join (descriptor, NULL);
114 4470 : posix_assert (rc);
115 4470 : }
116 :
117 1026 : void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_)
118 : {
119 : #if defined _POSIX_THREAD_PRIORITY_SCHEDULING && _POSIX_THREAD_PRIORITY_SCHEDULING >= 0
120 1026 : int policy = 0;
121 : struct sched_param param;
122 :
123 : #if _POSIX_THREAD_PRIORITY_SCHEDULING == 0 && defined _SC_THREAD_PRIORITY_SCHEDULING
124 : if (sysconf(_SC_THREAD_PRIORITY_SCHEDULING) < 0) {
125 : return;
126 : }
127 : #endif
128 1026 : int rc = pthread_getschedparam(descriptor, &policy, ¶m);
129 1026 : posix_assert (rc);
130 :
131 1026 : if(priority_ != -1)
132 : {
133 0 : param.sched_priority = priority_;
134 : }
135 :
136 1026 : if(schedulingPolicy_ != -1)
137 : {
138 0 : policy = schedulingPolicy_;
139 : }
140 :
141 : #ifdef __NetBSD__
142 : if(policy == SCHED_OTHER) param.sched_priority = -1;
143 : #endif
144 :
145 1026 : rc = pthread_setschedparam(descriptor, policy, ¶m);
146 1026 : posix_assert (rc);
147 : #endif
148 1026 : }
149 :
150 : #endif
151 :
152 :
153 :
154 :
155 :
|