All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Dam.cpp
Go to the documentation of this file.
1 /*
2  * Dam.cpp
3  *
4  * This file is part of the HausmiSEP project
5  *
6  * Copyright (C) 2012, 2013 Marco Alvarado (malvcr@gmail.com)
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #include <HSEP/Dam.h>
23 #include <HSEP/POSIX_Mutex.h>
24 
25 #include <unistd.h>
26 
27 namespace HSEP {
28 
29  Dam::Dam(bool pState, bool pShared) : aState(pState) {
30 
31  pthread_mutexattr_t vMutexAttr;
32  pthread_condattr_t vCondAttr;
33  pthread_mutexattr_init(&vMutexAttr);
34  pthread_condattr_init(&vCondAttr);
35  if (pShared) {
36  pthread_mutexattr_setpshared(&vMutexAttr,PTHREAD_PROCESS_SHARED);
37  pthread_condattr_setpshared (&vCondAttr,PTHREAD_PROCESS_SHARED);
38  }
39  else {
40  pthread_mutexattr_setpshared(&vMutexAttr,PTHREAD_PROCESS_PRIVATE);
41  pthread_condattr_setpshared (&vCondAttr,PTHREAD_PROCESS_PRIVATE);
42  }
43  pthread_mutex_init (&aConditionMutex,&vMutexAttr);
44  pthread_cond_init (&aConditionHandler,&vCondAttr);
45  pthread_mutex_init (&aWorkMutex,&vMutexAttr);
46  pthread_condattr_destroy (&vCondAttr);
47  pthread_mutexattr_destroy(&vMutexAttr);
48 
49  aShared = pShared;
50  aTriggered = false;
51  aWaiting = 0;
52  } // Dam constructor
53 
55  pthread_mutex_destroy (&aWorkMutex);
56  pthread_cond_destroy (&aConditionHandler);
57  pthread_mutex_destroy (&aConditionMutex);
58  } // Dam destructor
59 
60  void Dam::wait() {
61 
62  while (isClosed()) {
63 
64  PosixExclusiveScope vWaitScope(&aConditionMutex);
65  {
66  PosixExclusiveScope vScope(&aWorkMutex);
67  aWaiting++;
68  }
69  while (!aTriggered) {
70  if (isClosed()) {
71  pthread_cond_wait(&aConditionHandler,&aConditionMutex);
72  {
73  PosixExclusiveScope vScope(&aWorkMutex);
74  }
75  }
76  }
77  {
78  PosixExclusiveScope vScope(&aWorkMutex);
79  aWaiting--;
80  if (0 == aWaiting) {
81  aTriggered = false;
82  }
83  }
84  }
85 
86  } // Dam::wait
87 
88  void Dam::open() {
89 
90  if (isClosed()) {
91  {
92  PosixExclusiveScope vScope(&aWorkMutex);
93  aState = OPEN;
94  aTriggered = true;
95  }
96  {
97  PosixExclusiveScope vConditionScope(&aConditionMutex);
98  pthread_cond_broadcast(&aConditionHandler);
99  }
100  }
101 
102  } // Dam::open
103 
104  void Dam::close() {
105 
106  if (isOpen()) {
107 
108  // First, the internal state is changed
109  {
110  PosixExclusiveScope vScope(&aWorkMutex);
111  aState = CLOSED;
112  }
113 
114  // Then, all the waiting threads are notified
115  {
116  PosixExclusiveScope vNotifyScope(&aConditionMutex);
117  PosixExclusiveScope vScope(&aWorkMutex);
118  aTriggered = true;
119  pthread_cond_broadcast(&aConditionHandler);
120  }
121 
122  }
123 
124  } // Dam::close
125 
126  bool Dam::isOpen() {
127  bool vResult;
128  {
129  PosixExclusiveScope vScope(&aWorkMutex);
130  vResult = (OPEN == aState);
131  }
132  return vResult;
133  }
134 
135  bool Dam::isClosed() {
136  bool vResult;
137  {
138  PosixExclusiveScope vScope(&aWorkMutex);
139  vResult = (CLOSED == aState);
140  }
141  return vResult;
142  }
143 
144 } // HSEP namespace
145