Main MRPT website > C++ reference for MRPT 1.5.6
CSemaphore_LIN.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 #include <mrpt/config.h>
13 #if defined(MRPT_OS_LINUX)
14 
15 #include <mrpt/synch/CSemaphore.h>
17 #include <mrpt/system/threads.h>
18 
19 
20 #include <cstdlib>
21 #include <cstring>
22 #include <iostream>
23 #include <pthread.h>
24 #include <errno.h>
25 #include <fcntl.h> // O_CREAT
26 #include <semaphore.h>
27 #include <sys/timeb.h>
28 
29 using namespace mrpt;
30 using namespace mrpt::utils;
31 using namespace mrpt::synch;
32 using namespace std;
33 
34 
35 typedef struct
36 {
37  sem_t * semid;
38  bool has_to_free_mem;
39 } sem_private_struct, *sem_private;
40 
41 
42 /*---------------------------------------------------------------
43  CSemaphore
44 ---------------------------------------------------------------*/
45 CSemaphore::CSemaphore(
46  unsigned int initialCount,
47  unsigned int maxCount)
48 {
51 
52  // Reserve memory for my data:
53  m_data.resize( sizeof(sem_private_struct) );
54  sem_private token = m_data.getAsPtr<sem_private_struct>();
55 
56  // Unnamed semaphore:
57  token->has_to_free_mem = true; // sem_init() requires an already allocated "sem_t"
58  token->semid = static_cast<sem_t*>( malloc(sizeof(sem_t)) );
59 
60  if (sem_init(token->semid, 0 /*pshared:false*/, initialCount))
61  token->semid=(sem_t*)SEM_FAILED;
62 
63  // On error, launch an exception explaining it:
64  if (token->semid==SEM_FAILED)
65  THROW_EXCEPTION( format("Creating semaphore raised error: %s",strerror(errno) ) )
66 
67  //int sval; sem_getvalue(token->semid, &sval); std::cout << mrpt::format("Semaphore: Init val=%i desired initialCount=%i.\n",sval,initialCount);std::cout.flush();
68 
69  MRPT_END
70 }
71 
72 /*---------------------------------------------------------------
73  ~CSemaphore
74 ---------------------------------------------------------------*/
75 CSemaphore::~CSemaphore()
76 {
77  if (m_data.alias_count()==1)
78  {
79  sem_private token = m_data.getAsPtr<sem_private_struct>();
80 
81  // Unnamed sems: sem_destroy()
82  sem_destroy((sem_t *)token->semid);
83 
84  if (token->has_to_free_mem)
85  free(token->semid);
86  }
87 }
88 
89 /*---------------------------------------------------------------
90 Blocks until the count of the semaphore to be non-zero.
91 \param timeout_ms The timeout in milliseconds, or set to zero to wait indefinidely.
92 \return true if the semaphore has been signaled, false on timeout or any other error.
93 ---------------------------------------------------------------*/
94 bool CSemaphore::waitForSignal( unsigned int timelimit )
95 {
97 
98  sem_private token = m_data.getAsPtr<sem_private_struct>();
99 
100 
101  int rc;
102 
103  if (timelimit==0)
104  {
105  //{int sval; sem_getvalue(token->semid, &sval); std::cout << mrpt::format("Semaphore:wait1: val=%i.\n",sval);std::cout.flush();}
106  // No timeout
107  rc = sem_wait( token->semid );
108  }
109  else
110  {
111  // Prepare the "tm" struct with the absolute timeout timestamp:
112  struct timeb tp;
113 
114  const long sec = timelimit / 1000;
115  const long millisec = timelimit % 1000;
116  ftime( &tp );
117  tp.time += sec;
118  tp.millitm += millisec;
119  if( tp.millitm > 999 )
120  {
121  tp.millitm -= 1000;
122  tp.time++;
123  }
124 
125  struct timespec tm;
126  tm.tv_sec = tp.time;
127  tm.tv_nsec = tp.millitm * 1000000 ;
128 
129  // We have a timeout:
130  while ((rc = sem_timedwait( token->semid, &tm )) == -1 && errno == EINTR)
131  continue; // Restart if interrupted by handler
132  }
133 
134  // If there's an error != than a timeout, dump to stderr:
135  if (rc!=0 && errno!=ETIMEDOUT)
136  std::cerr << format("[CSemaphore::waitForSignal] In semaphore, error: %s\n", strerror(errno) );
137 
138  return rc==0; // true: all ok.
139 
140  MRPT_END
141 }
142 
143 /*---------------------------------------------------------------
144  Increments the count of the semaphore by a given amount.
145 ---------------------------------------------------------------*/
146 void CSemaphore::release(unsigned int increaseCount )
147 {
148  MRPT_START
149 
150  sem_private token = m_data.getAsPtr<sem_private_struct>();
151 
152  for (unsigned int i=0;i<increaseCount;i++)
153  if (sem_post(token->semid))
154  THROW_EXCEPTION( format("Increasing count of semaphore raised error: %s",strerror(errno) ) )
155 
156  MRPT_END
157 }
158 
159 
160 #endif // Linux
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
#define THROW_EXCEPTION(msg)
STL namespace.
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
This namespace provides multitask, synchronization utilities.
Definition: atomic_incr.h:29
#define MRPT_START
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLsizei maxCount
Definition: glext.h:3902



Page generated by Doxygen 1.8.14 for MRPT 1.5.6 Git: 4c65e8431 Tue Apr 24 08:18:17 2018 +0200 at lun oct 28 01:35:26 CET 2019