"Fossies" - the Fresh Open Source Software Archive

Member "netxms-3.8.166/src/libnetxms/threads.cpp" (23 Feb 2021, 6243 Bytes) of package /linux/misc/netxms-3.8.166.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "threads.cpp" see the Fossies "Dox" file reference documentation.

    1 /* 
    2 ** libnetxms - Common NetXMS utility library
    3 ** Copyright (C) 2003-2020 Victor Kirhenshtein
    4 **
    5 ** This program is free software; you can redistribute it and/or modify
    6 ** it under the terms of the GNU Lesser General Public License as published
    7 ** by the Free Software Foundation; either version 3 of the License, or
    8 ** (at your option) any later version.
    9 **
   10 ** This program is distributed in the hope that it will be useful,
   11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
   12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13 ** GNU General Public License for more details.
   14 **
   15 ** You should have received a copy of the GNU Lesser General Public License
   16 ** along with this program; if not, write to the Free Software
   17 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18 **
   19 ** File: threads.cpp
   20 **
   21 **/
   22 
   23 #include "libnetxms.h"
   24 
   25 /**
   26  * Mutex class constructor
   27  */
   28 Mutex::Mutex(bool fast)
   29 {
   30    m_mutex = fast ? MutexCreateFast() : MutexCreate();
   31    m_refCount = new VolatileCounter(1);
   32 }
   33 
   34 /**
   35  * Mutex class copy constructor
   36  */
   37 Mutex::Mutex(const Mutex& src)
   38 {
   39    InterlockedIncrement(src.m_refCount);
   40    m_mutex = src.m_mutex;
   41    m_refCount = src.m_refCount;
   42 }
   43 
   44 /**
   45  * Mutex destructor
   46  */
   47 Mutex::~Mutex()
   48 {
   49    if (InterlockedDecrement(m_refCount) == 0)
   50    {
   51       MutexDestroy(m_mutex);
   52       delete m_refCount;
   53    }
   54 }
   55 
   56 /**
   57  * Mutex assignment operator
   58  */
   59 Mutex& Mutex::operator =(const Mutex& src)
   60 {
   61    if (&src == this)
   62       return *this;
   63    if (InterlockedDecrement(m_refCount))
   64    {
   65       MutexDestroy(m_mutex);
   66       delete m_refCount;
   67    }
   68    InterlockedIncrement(src.m_refCount);
   69    m_mutex = src.m_mutex;
   70    m_refCount = src.m_refCount;
   71    return *this;
   72 }
   73 
   74 /**
   75  * R/W Lock class constructor
   76  */
   77 RWLock::RWLock()
   78 {
   79    m_rwlock = RWLockCreate();
   80    m_refCount = new VolatileCounter(1);
   81 }
   82 
   83 /**
   84  * R/W Lock class copy constructor
   85  */
   86 RWLock::RWLock(const RWLock& src)
   87 {
   88    InterlockedIncrement(src.m_refCount);
   89    m_rwlock = src.m_rwlock;
   90    m_refCount = src.m_refCount;
   91 }
   92 
   93 /**
   94  * R/W Lock destructor
   95  */
   96 RWLock::~RWLock()
   97 {
   98    if (InterlockedDecrement(m_refCount) == 0)
   99    {
  100       RWLockDestroy(m_rwlock);
  101       delete m_refCount;
  102    }
  103 }
  104 
  105 /**
  106  * R/W Lock assignment operator
  107  */
  108 RWLock& RWLock::operator =(const RWLock& src)
  109 {
  110    if (&src == this)
  111       return *this;
  112    if (InterlockedDecrement(m_refCount))
  113    {
  114       RWLockDestroy(m_rwlock);
  115       delete m_refCount;
  116    }
  117    InterlockedIncrement(src.m_refCount);
  118    m_rwlock = src.m_rwlock;
  119    m_refCount = src.m_refCount;
  120    return *this;
  121 }
  122 
  123 /**
  124  * Condition class constructor
  125  */
  126 Condition::Condition(bool broadcast)
  127 {
  128    m_condition = ConditionCreate(broadcast);
  129    m_refCount = new VolatileCounter(1);
  130 }
  131 
  132 /**
  133  * Condition class copy constructor
  134  */
  135 Condition::Condition(const Condition& src)
  136 {
  137    InterlockedIncrement(src.m_refCount);
  138    m_condition = src.m_condition;
  139    m_refCount = src.m_refCount;
  140 }
  141 
  142 /**
  143  * Condition destructor
  144  */
  145 Condition::~Condition()
  146 {
  147    if (InterlockedDecrement(m_refCount) == 0)
  148    {
  149       ConditionDestroy(m_condition);
  150       delete m_refCount;
  151    }
  152 }
  153 
  154 /**
  155  * Condition assignment operator
  156  */
  157 Condition& Condition::operator =(const Condition& src)
  158 {
  159    if (&src == this)
  160       return *this;
  161    if (InterlockedDecrement(m_refCount))
  162    {
  163       ConditionDestroy(m_condition);
  164       delete m_refCount;
  165    }
  166    InterlockedIncrement(src.m_refCount);
  167    m_condition = src.m_condition;
  168    m_refCount = src.m_refCount;
  169    return *this;
  170 }
  171 
  172 #ifndef _WIN32
  173 
  174 #include <signal.h>
  175 #include <sys/wait.h>
  176 
  177 #if HAVE_SYS_UTSNAME_H
  178 #include <sys/utsname.h>
  179 #endif
  180 
  181 /**
  182  * Block all signals on a thread
  183  */
  184 void LIBNETXMS_EXPORTABLE BlockAllSignals(bool processWide, bool allowInterrupt)
  185 {
  186    sigset_t signals;
  187    sigemptyset(&signals);
  188    sigaddset(&signals, SIGTERM);
  189    if (!allowInterrupt)
  190       sigaddset(&signals, SIGINT);
  191    sigaddset(&signals, SIGSEGV);
  192    sigaddset(&signals, SIGCHLD);
  193    sigaddset(&signals, SIGHUP);
  194    sigaddset(&signals, SIGUSR1);
  195    sigaddset(&signals, SIGUSR2);
  196 #if !defined(__sun) && !defined(_AIX) && !defined(__hpux)
  197    sigaddset(&signals, SIGPIPE);
  198 #endif
  199    if (processWide)
  200       sigprocmask(SIG_BLOCK, &signals, NULL);
  201    else
  202       pthread_sigmask(SIG_BLOCK, &signals, NULL);
  203 }
  204 
  205 /**
  206  * Start main loop and signal handler for daemon
  207  */
  208 void LIBNETXMS_EXPORTABLE StartMainLoop(ThreadFunction pfSignalHandler, ThreadFunction pfMain)
  209 {
  210    THREAD hThread;
  211    struct utsname un;
  212    int nModel = 0;
  213 
  214    if (uname(&un) != -1)
  215    {
  216       char *ptr;
  217 
  218       ptr = strchr(un.release, '.');
  219       if (ptr != NULL)
  220          *ptr = 0;
  221       if (!stricmp(un.sysname, "FreeBSD") && (atoi(un.release) >= 5))
  222          nModel = 1;
  223    }
  224 
  225    if (pfMain != NULL)
  226    {
  227       if (nModel == 0)
  228       {
  229          hThread = ThreadCreateEx(pfMain, 0, NULL);
  230          pfSignalHandler(NULL);
  231          ThreadJoin(hThread);
  232       }
  233       else
  234       {
  235          hThread = ThreadCreateEx(pfSignalHandler, 0, NULL);
  236          pfMain(NULL);
  237          ThreadJoin(hThread);
  238       }
  239    }
  240    else
  241    {
  242       if (nModel == 0)
  243       {
  244          pfSignalHandler(NULL);
  245       }
  246       else
  247       {
  248          hThread = ThreadCreateEx(pfSignalHandler, 0, NULL);
  249          ThreadJoin(hThread);
  250       }
  251    }
  252 }
  253 
  254 #endif   /* _WIN32 */
  255 
  256 #ifdef _WIN32
  257 extern HRESULT (WINAPI *imp_SetThreadDescription)(HANDLE, PCWSTR);
  258 
  259 /**
  260 * Set thread name. Thread can be set to INVALID_THREAD_HANDLE to change name of current thread.
  261 */
  262 void LIBNETXMS_EXPORTABLE ThreadSetName(THREAD thread, const char *name)
  263 {
  264    if (imp_SetThreadDescription != NULL)
  265    {
  266       WCHAR wname[256];
  267       MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, name, -1, wname, 256);
  268       imp_SetThreadDescription((thread != INVALID_THREAD_HANDLE) ? thread->handle : GetCurrentThread(), wname);
  269    }
  270    else
  271    {
  272       THREADNAME_INFO info;
  273       info.dwType = 0x1000;
  274       info.szName = name;
  275       info.dwThreadID = (thread != INVALID_THREAD_HANDLE) ? thread->id : (DWORD)-1;
  276       info.dwFlags = 0;
  277 #pragma warning(push)
  278 #pragma warning(disable: 6320 6322)
  279       __try
  280       {
  281          RaiseException(0x406D1388, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
  282       }
  283       __except (EXCEPTION_EXECUTE_HANDLER)
  284       {
  285       }
  286 #pragma warning(pop)
  287    }
  288 }
  289 
  290 #endif   /* _WIN32 */