Coverage Report

Created: 2025-12-31 07:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/Magick++/lib/Thread.cpp
Line
Count
Source
1
// This may look like C code, but it is really -*- C++ -*-
2
//
3
// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
4
//
5
// Implementation of thread support
6
//
7
8
#define MAGICK_IMPLEMENTATION
9
#define MAGICK_PLUSPLUS_IMPLEMENTATION
10
11
#include "Magick++/Thread.h"
12
#include "Magick++/Exception.h"
13
14
#include <string.h>
15
16
// Default constructor
17
Magick::MutexLock::MutexLock(void)
18
#if defined(HasPTHREADS)
19
  // POSIX threads
20
  : _mutex()
21
{
22
  ::pthread_mutexattr_t attr;
23
  int sysError;
24
  if ( (sysError = ::pthread_mutexattr_init( &attr )) == 0 )
25
    if ( (sysError = ::pthread_mutex_init( &_mutex, &attr )) == 0 )
26
      {
27
        ::pthread_mutexattr_destroy( &attr );
28
        return;
29
      }
30
  throwExceptionExplicit( OptionError, "mutex initialization failed",
31
                          strerror(sysError) );
32
}
33
#else
34
#if defined(_VISUALC_) && defined(_MT)
35
// Win32 threads
36
  : _mutex()
37
{
38
  SECURITY_ATTRIBUTES security;
39
40
  /* Allow the semaphore to be inherited */
41
  security.nLength = sizeof(security);
42
  security.lpSecurityDescriptor = NULL;
43
  security.bInheritHandle = TRUE;
44
45
  /* Create the semaphore, with initial value signaled */
46
  _mutex.id = ::CreateSemaphore(&security, 1, MAXSEMLEN, NULL);
47
  if ( _mutex.id != NULL )
48
    return;
49
  throwExceptionExplicit( OptionError, "mutex initialization failed" );
50
}
51
#else
52
// Threads not supported
53
1.16M
{
54
1.16M
}
55
#endif
56
#endif
57
58
// Destructor
59
Magick::MutexLock::~MutexLock(void)
60
1.16M
{
61
#if defined(HasPTHREADS)
62
  int sysError;
63
  if ( (sysError = ::pthread_mutex_destroy( &_mutex )) == 0 )
64
    return;
65
  throwExceptionExplicit( OptionError, "mutex destruction failed",
66
                          strerror(sysError) );
67
#endif
68
#if defined(_MT) && defined(_VISUALC_)
69
  if ( ::CloseHandle(_mutex.id) != 0 )
70
    return;
71
  throwExceptionExplicit( OptionError, "mutex destruction failed" );
72
#endif
73
1.16M
}
74
75
// Lock mutex
76
void Magick::MutexLock::lock(void)
77
3.24M
{
78
#if defined(HasPTHREADS)
79
  int sysError;
80
  if ( (sysError = ::pthread_mutex_lock( &_mutex )) == 0)
81
    return;
82
  throwExceptionExplicit( OptionError, "mutex lock failed",
83
                          strerror(sysError));
84
#endif
85
#if defined(_MT) && defined(_VISUALC_)
86
#if 1
87
  if (WaitForSingleObject(_mutex.id,INFINITE) != WAIT_FAILED)
88
    return;
89
  throwExceptionExplicit( OptionError, "mutex lock failed" );
90
#else
91
  // Following code  is not known to work correctly yet.
92
  while(1)
93
  {
94
    DWORD status=MsgWaitForMultipleObjects(1, &_mutex.id, FALSE, INFINITE,
95
      QS_ALLEVENTS);
96
    // Loop if return was due to message received (which we don't care about).
97
    if (status == (WAIT_OBJECT_0+1))
98
      continue;
99
    // If return was due to handle state change, then object is available.
100
    if ((status - WAIT_OBJECT_0) == 0)
101
      return;
102
   }
103
  // If we get here, then there was an unexpected return value.
104
  throwExceptionExplicit( OptionError, "mutex lock failed" );
105
#endif
106
#endif
107
3.24M
}
108
109
// Unlock mutex
110
void Magick::MutexLock::unlock(void)
111
3.24M
{
112
#if defined(HasPTHREADS)
113
  int sysError;
114
  if ( (sysError = ::pthread_mutex_unlock( &_mutex )) == 0)
115
    return;
116
  throwExceptionExplicit( OptionError, "mutex unlock failed",
117
                          strerror(sysError) );
118
#endif
119
#if defined(_MT) && defined(_VISUALC_)
120
  if ( ReleaseSemaphore(_mutex.id, 1, NULL) == TRUE )
121
    return;
122
  throwExceptionExplicit( OptionError, "mutex unlock failed" );
123
#endif
124
3.24M
}