14e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
24e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * @{
34e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * @file
44e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *
54e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * Semaphore implementation (pthread wrapper).
64e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *
74e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
87b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim *
94e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * Redistribution and use in source and binary forms, with or without
104e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * modification, are permitted provided that the following conditions
114e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * are met:
124e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 1. Redistributions of source code must retain the above copyright
134e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    notice, this list of conditions and the following disclaimer.
144e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 2. Redistributions in binary form must reproduce the above copyright
154e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    notice, this list of conditions and the following disclaimer in the
164e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    documentation and/or other materials provided with the distribution.
174e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * 3. The name of the author may not be used to endorse or promote
184e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    products derived from this software without specific prior
194e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *    written permission.
204e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park *
214e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
224e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
234e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
244e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
254e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
264e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
274e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
284e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
294e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
304e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
314e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
324e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park */
334e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <time.h>
344e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <limits.h>
354e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include "CSemaphore.h"
364e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park#include <stdio.h>
374e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
384e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
397b143edf281bed18c8ebd0733465f3af5af327ebJungtae KimCSemaphore::CSemaphore(int size) : m_waiters_count(0), m_count(size)
404e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park{
417b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_init(&m_mutex, NULL);
427b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_cond_init(&m_cond, NULL);
434e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
444e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
454e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
464e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
474e9e8c9c0169b40318386436d762c3d73cf4c328DongJin ParkCSemaphore::~CSemaphore()
484e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park{
497b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_destroy(&m_mutex);
507b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_cond_destroy(&m_cond);
514e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
524e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
534e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
544e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
554e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid CSemaphore::wait()
564e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park{
577b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_lock(&m_mutex);
587b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    m_waiters_count ++;
597b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    while ( m_count == 0 )
607b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        pthread_cond_wait(&m_cond, &m_mutex);
617b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    m_waiters_count --;
627b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    m_count --;
637b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_unlock(&m_mutex);
644e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
654e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
664e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
674e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkbool CSemaphore::wait(int sec)
684e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park{
697b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    int rc = 0;
707b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    struct timespec tm;
717b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (sec < 0)
727b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        sec = LONG_MAX;
737b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    clock_gettime(CLOCK_REALTIME, &tm);
747b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    tm.tv_sec += sec;
757b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim
767b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_lock(&m_mutex);
777b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    m_waiters_count ++;
787b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if ( m_count == 0 ) {
797b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        rc = pthread_cond_timedwait(&m_cond, &m_mutex, &tm);
807b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    }
817b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    m_waiters_count --;
827b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // Decrement only if waiting actually succeeded, otherwise we
837b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    // just timed out
847b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if (!rc)
857b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        m_count --;
867b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_unlock(&m_mutex);
877b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return (rc == 0);
884e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
894e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
904e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
914e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
924e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkbool CSemaphore::wouldWait()
934e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park{
947b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    bool ret = false;
957b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_lock(&m_mutex);
967b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if ( m_count == 0 )
977b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        ret = true;
987b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_unlock(&m_mutex);
997b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    return ret;
1004e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
1014e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1024e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1034e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park//------------------------------------------------------------------------------
1044e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Parkvoid CSemaphore::signal()
1054e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park{
1067b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_lock(&m_mutex);
1077b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    if ( m_waiters_count > 0 )
1087b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim        pthread_cond_signal(&m_cond);
1097b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    m_count ++;
1107b143edf281bed18c8ebd0733465f3af5af327ebJungtae Kim    pthread_mutex_unlock(&m_mutex);
1114e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park}
1124e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park
1134e9e8c9c0169b40318386436d762c3d73cf4c328DongJin Park/** @} */
114