libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
posix_locking.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2004 by J.M.McGuiness, coder@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "../core/hp_timer.hpp"
20 #include "posix_locking.hpp"
21 
22 namespace jmmcg { namespace LIBJMMCG_VER_NAMESPACE { namespace ppd { namespace pthreads {
23 
25 anon_semaphore::lock(const timeout_type period) noexcept(false) {
26  using timer_t=hp_timer<ppd::generic_traits::api_type::posix_pthreads, heavyweight_threading>;
27 
28  if (period==0) {
29  return try_lock();
30  } else if (period<lock_traits::infinite_timeout()) {
31  static const timer_t time;
32  timer_t::time_utc_t now=time.current_time();
33  now.tv_nsec+=(period%1000)*1000000;
34  now.tv_sec+=period/1000+now.tv_nsec/1000000000;
35  now.tv_nsec=now.tv_nsec%1000000000;
36  assert(now.tv_nsec>=0);
37  assert(now.tv_nsec<1000000000);
38  if (sem_timedwait(&sem, &now)==-1) {
39  switch (errno) {
40  case ETIMEDOUT: return lock_traits::atom_unset;
41  case EINTR: return lock_traits::atom_interrupted;
42  case EAGAIN: return lock_traits::atom_max_recurse;
43  case EINVAL:
44  default: return lock_traits::atom_abandoned;
45  };
46  }
47  return lock_traits::atom_set;
48  } else {
49  return lock();
50  }
51 }
52 
53 } } } }