~josejuan-sanchez/esajpip/debian

« back to all changes in this revision

Viewing changes to src/ipc/mutex.cc

  • Committer: José Juan Sánchez Hernández
  • Date: 2013-04-02 18:14:26 UTC
  • Revision ID: josejuan.sanchez@gmail.com-20130402181426-07xn3djblburck53
Version for Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <assert.h>
 
2
#include <errno.h>
 
3
#include <sched.h>
 
4
#include "mutex.h"
 
5
 
 
6
 
 
7
namespace ipc
 
8
{
 
9
 
 
10
  bool Mutex::Init(bool initial_owner)
 
11
  {
 
12
    assert(!IsValid());
 
13
 
 
14
    bool res = false;
 
15
 
 
16
    pthread_mutexattr_t mutexAttr;
 
17
 
 
18
    pthread_mutexattr_init(&mutexAttr);
 
19
    pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);
 
20
    pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_PRIVATE);
 
21
 
 
22
    if(!pthread_mutex_init(&mutex, &mutexAttr)) {
 
23
      if(initial_owner) res = (Wait() == WAIT_OBJECT);
 
24
      else res = true;
 
25
    }
 
26
 
 
27
    if(!res) pthread_mutex_destroy(&mutex);
 
28
    pthread_mutexattr_destroy(&mutexAttr);
 
29
 
 
30
    if(res) IPCObject::Init();
 
31
    return res;
 
32
  }
 
33
 
 
34
  WaitResult Mutex::Wait(int time_out)
 
35
  {
 
36
    assert(IsValid());
 
37
 
 
38
    if(time_out <= -1) {
 
39
      if(pthread_mutex_lock(&mutex)) return WAIT_ERROR;
 
40
      else {
 
41
        locker = pthread_self();
 
42
        return WAIT_OBJECT;
 
43
      }
 
44
 
 
45
    } else {
 
46
      int res;
 
47
      struct timespec delay = {0, 1000000};
 
48
 
 
49
      while((res = pthread_mutex_trylock(&mutex)) == EBUSY) {
 
50
        if(!time_out) return WAIT_TIMEOUT;
 
51
        else {
 
52
          nanosleep(&delay, NULL);
 
53
          time_out--;
 
54
        }
 
55
      }
 
56
 
 
57
      if(res) return WAIT_ERROR;
 
58
      else {
 
59
        locker = pthread_self();
 
60
        return WAIT_OBJECT;
 
61
      }
 
62
    }
 
63
  }
 
64
 
 
65
  bool Mutex::Release()
 
66
  {
 
67
    assert(IsValid());
 
68
 
 
69
    if(locker != pthread_self()) return false;
 
70
    else {
 
71
      if(pthread_mutex_unlock(&mutex)) return false;
 
72
      else {
 
73
        //pthread_yield();
 
74
        sched_yield();
 
75
        return true;
 
76
      }
 
77
    }
 
78
  }
 
79
 
 
80
  bool Mutex::Dispose()
 
81
  {
 
82
    if(!IsValid()) return true;
 
83
    else {
 
84
      Release();
 
85
 
 
86
      if(pthread_mutex_destroy(&mutex)) return false;
 
87
      else {
 
88
        IPCObject::Dispose();
 
89
        return true;
 
90
      }
 
91
    }
 
92
  }
 
93
 
 
94
}