00001 // 00002 // Copyright (c) Benjamin Kaufmann 00003 // 00004 // This is free software; you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation; either version 2 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This file is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this file; if not, write to the Free Software 00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 // 00018 #ifndef ALARM_HELPER_H_INCLUDED 00019 #define ALARM_HELPER_H_INCLUDED 00020 00021 // Alarm handling 00023 #include <signal.h> 00024 // Schedules an alarm signal 00025 // The function causes the system to generate a SIGALRM 00026 // signal for the process after the number of real-time seconds 00027 // given in sec. 00028 // 00029 // If seconds is 0, a pending alarm request, if any, is cancelled. 00030 // 00031 // Alarm requests are not stacked; only one SIGALRM generation 00032 // can be scheduled with this function; 00033 // 00034 // setAlarm() returns a value > 0 if the alarm request was set. 00035 // Otherwise it returns 0. 00036 int setAlarm(unsigned sec); 00037 00038 // Sets the SIGALRM handler 00039 void setAlarmHandler(void(*f)(int)); 00040 00041 unsigned long initMainThread(); 00042 void resetMainThread(); 00043 void protectMainThread(bool); 00044 00045 // Implementation: 00046 // - On POSIX-systems setAlarm() calls alarm() and setAlarmHandler() calls signal() 00047 // - On Windows a separate alarm thread is created that 00048 // waits for sec seconds on a termination event and, 00049 // if the event is not signaled, calls the installed alarm handler in the context 00050 // of the alarm thread. 00051 // NOTE: Since the handler is called from a different thread, alarm 00052 // handling is subject to race-conditions. 00053 // USe lockAlarm(), unlockAlarm() to protect functions that 00054 // are not thread-safe and are called by the handler 00055 #if defined(_WIN32) || defined(_WIN64) 00056 void lockAlarm(); 00057 void unlockAlarm(); 00058 #else 00059 inline void lockAlarm() {} 00060 inline void unlockAlarm() {} 00061 #endif 00062 00063 struct ScopedAlarmLock { 00064 ScopedAlarmLock() { lockAlarm(); } 00065 ~ScopedAlarmLock() { unlockAlarm(); } 00066 }; 00067 00068 #define SCOPE_ALARM_LOCK() ScopedAlarmLock __alarm_lock__ 00069 00070 00071 #if !defined(SIGALRM) 00072 #define SIGALRM 14 00073 #endif 00074 00075 #endif