mutex.hpp 3.14 KB
Newer Older
Martin Sustrik's avatar
Martin Sustrik committed
1
/*
2
    Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file
Martin Sustrik's avatar
Martin Sustrik committed
3 4 5 6

    This file is part of 0MQ.

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

    0MQ 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
14
    GNU Lesser General Public License for more details.
Martin Sustrik's avatar
Martin Sustrik committed
15

16
    You should have received a copy of the GNU Lesser General Public License
Martin Sustrik's avatar
Martin Sustrik committed
17 18 19
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

Martin Sustrik's avatar
Martin Sustrik committed
20 21
#ifndef __ZMQ_MUTEX_HPP_INCLUDED__
#define __ZMQ_MUTEX_HPP_INCLUDED__
Martin Sustrik's avatar
Martin Sustrik committed
22 23 24 25 26 27

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

//  Mutex class encapsulates OS mutex in a platform-independent way.

Martin Sustrik's avatar
Martin Sustrik committed
28
#ifdef ZMQ_HAVE_WINDOWS
Martin Sustrik's avatar
Martin Sustrik committed
29 30 31

#include "windows.hpp"

Martin Sustrik's avatar
Martin Sustrik committed
32
namespace zmq
Martin Sustrik's avatar
Martin Sustrik committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
{

    class mutex_t
    {
    public:
        inline mutex_t ()
        {
            InitializeCriticalSection (&cs);
        }

        inline ~mutex_t ()
        {
            DeleteCriticalSection (&cs);
        }

        inline void lock ()
        {
            EnterCriticalSection (&cs);
        }

danielkr's avatar
danielkr committed
53 54
        inline bool try_lock ()
        {
55
            return (TryEnterCriticalSection (&cs)) ? true : false;
danielkr's avatar
danielkr committed
56 57
        }

Martin Sustrik's avatar
Martin Sustrik committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
        inline void unlock ()
        {
            LeaveCriticalSection (&cs);
        }

    private:

        CRITICAL_SECTION cs;

        //  Disable copy construction and assignment.
        mutex_t (const mutex_t&);
        void operator = (const mutex_t&);
    };

}

#else

#include <pthread.h>

Martin Sustrik's avatar
Martin Sustrik committed
78
namespace zmq
Martin Sustrik's avatar
Martin Sustrik committed
79
{
80

Martin Sustrik's avatar
Martin Sustrik committed
81 82 83 84 85 86
    class mutex_t
    {
    public:
        inline mutex_t ()
        {
            int rc = pthread_mutex_init (&mutex, NULL);
87
            posix_assert (rc);
Martin Sustrik's avatar
Martin Sustrik committed
88
        }
89

Martin Sustrik's avatar
Martin Sustrik committed
90 91 92
        inline ~mutex_t ()
        {
            int rc = pthread_mutex_destroy (&mutex);
93
            posix_assert (rc);
Martin Sustrik's avatar
Martin Sustrik committed
94
        }
95

Martin Sustrik's avatar
Martin Sustrik committed
96 97 98
        inline void lock ()
        {
            int rc = pthread_mutex_lock (&mutex);
99
            posix_assert (rc);
Martin Sustrik's avatar
Martin Sustrik committed
100
        }
101

danielkr's avatar
danielkr committed
102 103 104 105 106 107 108 109 110 111
        inline bool try_lock ()
        {
            int rc = pthread_mutex_trylock (&mutex);
            if (rc == EBUSY)
                return false;

            posix_assert (rc);
            return true;
        }

Martin Sustrik's avatar
Martin Sustrik committed
112 113 114
        inline void unlock ()
        {
            int rc = pthread_mutex_unlock (&mutex);
115
            posix_assert (rc);
Martin Sustrik's avatar
Martin Sustrik committed
116
        }
117

Martin Sustrik's avatar
Martin Sustrik committed
118
    private:
119

Martin Sustrik's avatar
Martin Sustrik committed
120
        pthread_mutex_t mutex;
121

122
        // Disable copy construction and assignment.
Martin Sustrik's avatar
Martin Sustrik committed
123
        mutex_t (const mutex_t&);
124
        const mutex_t &operator = (const mutex_t&);
Martin Sustrik's avatar
Martin Sustrik committed
125
    };
126

Martin Sustrik's avatar
Martin Sustrik committed
127 128 129 130
}

#endif

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

namespace zmq
{
    struct scoped_lock_t
    {
        scoped_lock_t (mutex_t& mutex_)
            : mutex (mutex_)
        {
            mutex.lock ();
        }

        ~scoped_lock_t ()
        {
            mutex.unlock ();
        }

    private:

        mutex_t& mutex;

        // Disable copy construction and assignment.
        scoped_lock_t (const scoped_lock_t&);
        const scoped_lock_t &operator = (const scoped_lock_t&);
    };
}

Martin Sustrik's avatar
Martin Sustrik committed
157
#endif