thread.cpp 3.79 KB
Newer Older
Martin Sustrik's avatar
Martin Sustrik committed
1
/*
2
    Copyright (c) 2007-2015 Contributors as noted in the AUTHORS file
Martin Sustrik's avatar
Martin Sustrik committed
3

4
    This file is part of libzmq, the ZeroMQ core engine in C++.
Martin Sustrik's avatar
Martin Sustrik committed
5

6 7 8
    libzmq is free software; you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License (LGPL) as published
    by the Free Software Foundation; either version 3 of the License, or
Martin Sustrik's avatar
Martin Sustrik committed
9 10
    (at your option) any later version.

11 12 13 14 15 16 17 18 19 20 21 22 23 24
    As a special exception, the Contributors give you permission to link
    this library with independent modules to produce an executable,
    regardless of the license terms of these independent modules, and to
    copy and distribute the resulting executable under terms of your choice,
    provided that you also meet, for each linked independent module, the
    terms and conditions of the license of that module. An independent
    module is a module which is not derived from or based on this library.
    If you modify this library, you must extend this exception to your
    version of the library.

    libzmq is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    License for more details.
Martin Sustrik's avatar
Martin Sustrik committed
25

26
    You should have received a copy of the GNU Lesser General Public License
Martin Sustrik's avatar
Martin Sustrik committed
27 28 29 30 31 32 33
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "thread.hpp"
#include "err.hpp"
#include "platform.hpp"

Martin Sustrik's avatar
Martin Sustrik committed
34
#ifdef ZMQ_HAVE_WINDOWS
Martin Sustrik's avatar
Martin Sustrik committed
35

36 37
extern "C"
{
boris@boressoft.ru's avatar
boris@boressoft.ru committed
38
#if defined _WIN32_WCE
39
    static DWORD thread_routine (LPVOID arg_)
boris@boressoft.ru's avatar
boris@boressoft.ru committed
40
#else
41
    static unsigned int __stdcall thread_routine (void *arg_)
boris@boressoft.ru's avatar
boris@boressoft.ru committed
42
#endif
43
    {
44
        zmq::thread_t *self = (zmq::thread_t*) arg_;
45 46 47 48 49
        self->tfn (self->arg);
        return 0;
    }
}

Martin Sustrik's avatar
Martin Sustrik committed
50
void zmq::thread_t::start (thread_fn *tfn_, void *arg_)
Martin Sustrik's avatar
Martin Sustrik committed
51 52
{
    tfn = tfn_;
Pieter Hintjens's avatar
Pieter Hintjens committed
53
    arg = arg_;
54
#if defined _WIN32_WCE
boris@boressoft.ru's avatar
boris@boressoft.ru committed
55 56 57
    descriptor = (HANDLE) CreateThread (NULL, 0,
        &::thread_routine, this, 0 , NULL);
#else
Martin Sustrik's avatar
Martin Sustrik committed
58
    descriptor = (HANDLE) _beginthreadex (NULL, 0,
59
        &::thread_routine, this, 0 , NULL);
boris@boressoft.ru's avatar
boris@boressoft.ru committed
60
#endif
61
    win_assert (descriptor != NULL);
Martin Sustrik's avatar
Martin Sustrik committed
62 63
}

Martin Sustrik's avatar
Martin Sustrik committed
64
void zmq::thread_t::stop ()
Martin Sustrik's avatar
Martin Sustrik committed
65 66 67
{
    DWORD rc = WaitForSingleObject (descriptor, INFINITE);
    win_assert (rc != WAIT_FAILED);
68
    BOOL rc2 = CloseHandle (descriptor);
69
    win_assert (rc2 != 0);
Martin Sustrik's avatar
Martin Sustrik committed
70 71
}

72 73 74 75 76
void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_)
{
    // not implemented
}

Martin Sustrik's avatar
Martin Sustrik committed
77 78 79 80
#else

#include <signal.h>

81 82 83 84
extern "C"
{
    static void *thread_routine (void *arg_)
    {
85 86
#if !defined ZMQ_HAVE_OPENVMS && !defined ZMQ_HAVE_ANDROID
        //  Following code will guarantee more predictable latencies as it'll
87 88 89 90 91
        //  disallow any signal handling in the I/O thread.
        sigset_t signal_set;
        int rc = sigfillset (&signal_set);
        errno_assert (rc == 0);
        rc = pthread_sigmask (SIG_BLOCK, &signal_set, NULL);
92
        posix_assert (rc);
93
#endif
94

95
        zmq::thread_t *self = (zmq::thread_t*) arg_;
96 97 98 99 100
        self->tfn (self->arg);
        return NULL;
    }
}

Martin Sustrik's avatar
Martin Sustrik committed
101
void zmq::thread_t::start (thread_fn *tfn_, void *arg_)
Martin Sustrik's avatar
Martin Sustrik committed
102 103
{
    tfn = tfn_;
Pieter Hintjens's avatar
Pieter Hintjens committed
104
    arg = arg_;
Martin Sustrik's avatar
Martin Sustrik committed
105
    int rc = pthread_create (&descriptor, NULL, thread_routine, this);
106
    posix_assert (rc);
Martin Sustrik's avatar
Martin Sustrik committed
107 108
}

Martin Sustrik's avatar
Martin Sustrik committed
109
void zmq::thread_t::stop ()
Martin Sustrik's avatar
Martin Sustrik committed
110 111
{
    int rc = pthread_join (descriptor, NULL);
112
    posix_assert (rc);
Martin Sustrik's avatar
Martin Sustrik committed
113 114
}

115 116
void zmq::thread_t::setSchedulingParameters(int priority_, int schedulingPolicy_)
{
117
#if !defined ZMQ_HAVE_ZOS && !defined ZMQ_HAVE_HPUX
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    int policy = 0;
    struct sched_param param;

    int rc = pthread_getschedparam(descriptor, &policy, &param);
    posix_assert (rc);

    if(priority_ != -1)
    {
        param.sched_priority = priority_;
    }

    if(schedulingPolicy_ != -1)
    {
        policy = schedulingPolicy_;
    }

    rc = pthread_setschedparam(descriptor, policy, &param);
    posix_assert (rc);
136
#endif
137 138
}

Martin Sustrik's avatar
Martin Sustrik committed
139 140 141 142 143 144
#endif