Project: engagement_recognition License: BSD Dependencies:
Used by:
None |
engagement_recognition/src/recognition/semaphores/semaphore.cppGo to the documentation of this file.00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2010, Worcester Polytechnic Institute 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Worcester Polytechnic Institute. nor the names 00018 * of its contributors may be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 // @author Brett Ponsler (bponsler (at) wpi (dot) edu) 00035 #include "semaphore.h" 00036 #include "errno.h" 00037 00038 #include "../lib/engagement_params.h" 00039 #include <boost/interprocess/sync/posix/ptime_to_timespec.hpp> 00040 00041 Semaphore::Semaphore(int value) 00042 { 00043 // Create the prefix for the logger 00044 std::string prefix = std::string(EngagementParams::getRecogTag()) + 00045 std::string(EngagementParams::getSemaphoreTag()); 00046 00047 // Create the logger for the actor off of the RNode logger 00048 this->setLogger(prefix); 00049 00050 // Create memory for the semaphore 00051 // NOTE: This fixed a problem with timed wait where it returns ENOSYS 00052 memset(&this->semaphore_, 0, sizeof(sem_t)); 00053 00054 // Initialize the semaphore to the value 00055 if(sem_init(&this->semaphore_, 0, value) < 0) 00056 this->fatal("Unable to initialize the semaphore with value [%d].", value); 00057 } 00058 00059 void Semaphore::post() 00060 { 00061 // Post the semaphore 00062 sem_post(&this->semaphore_); 00063 } 00064 00065 void Semaphore::wait() 00066 { 00067 // Wait on the semaphore 00068 sem_wait(&this->semaphore_); 00069 } 00070 00071 bool Semaphore::tryWait() 00072 { 00073 // Try to wait on the semaphore 00074 int ret = sem_trywait(&this->semaphore_); 00075 00076 // Return the success of the try wait 00077 return (ret == 0); 00078 } 00079 00080 bool Semaphore::timedWait(double time) 00081 { 00082 // Cannot wait less than zero seconds 00083 if (time < 0) 00084 { 00085 this->warn("Cannot wait for less than zero seconds."); 00086 return false; 00087 } 00088 00089 // Create the maximum time this semaphore should block for 00090 boost::posix_time::ptime duration = 00091 boost::posix_time::microsec_clock::universal_time() + 00092 boost::posix_time::millisec(time * 1000); 00093 00094 // Convert the boost time into a timespec object 00095 timespec tspec = boost::interprocess::detail::ptime_to_timespec(duration); 00096 00097 // Wait on the semaphore 00098 int ret = sem_timedwait(&this->semaphore_, &tspec); 00099 00100 // Return true if this succeeded 00101 // Set errno to the return value if it's larger than zero 00102 if (ret == 0) 00103 return true; 00104 else if (ret > 0) 00105 errno = ret; 00106 00107 // If the semaphore did not timeout print out an error 00108 if (errno != ETIMEDOUT) 00109 { 00110 this->error("Failed to call timed wait for [%lf] seconds. error: [%d]", 00111 time, errno); 00112 } 00113 00114 // The semaphore timed out or failed to be called 00115 return false; 00116 } 00117 00118 int Semaphore::getValue() 00119 { 00120 int value; 00121 00122 // Grab the value of the semaphore 00123 sem_getvalue(&this->semaphore_, &value); 00124 00125 return value; 00126 } |