File: ThreadSpecificData.cxx

package info (click to toggle)
itksnap 3.4.0-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 10,196 kB
  • ctags: 9,196
  • sloc: cpp: 62,895; sh: 175; makefile: 13
file content (115 lines) | stat: -rw-r--r-- 2,622 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "ThreadSpecificData.h"
#include "itkMultiThreader.h"
#include "IRISException.h"

#if defined(ITK_USE_PTHREADS)

void ThreadSpecificDataSupport::Deleter(void *p)
{
  free(p);
}

ThreadSpecificDataSupport::ThreadSpecificDataSupport()
{
  // Allocate storage for a key
  pthread_key_t *pkey = new pthread_key_t[1];

  // Create the key
  int rc = pthread_key_create(pkey, &ThreadSpecificDataSupport::Deleter);
  if(rc)
    throw IRISException("pthread_key_create failed with rc = %d", rc);

  // Store the key
  m_KeyPointer = pkey;
}

ThreadSpecificDataSupport::~ThreadSpecificDataSupport()
{
  // Delete the key
  pthread_key_t *pkey = (pthread_key_t *) m_KeyPointer;
  int rc = pthread_key_delete(pkey[0]);
  if(rc)
    throw IRISException("pthread_key_delete failed with rc = %d", rc);
}

void *ThreadSpecificDataSupport::GetPtrCreateIfNeeded(size_t data_size)
{
  pthread_key_t *pkey = (pthread_key_t *) m_KeyPointer;
  void *pdata = pthread_getspecific(pkey[0]);
  if(!pdata)
    {
    pdata = malloc(data_size);
    int rc  = pthread_setspecific(pkey[0], pdata);
    if(rc)
      throw IRISException("pthread_setspecific failed with rc = %d", rc);
    }
  return pdata;
}

void *ThreadSpecificDataSupport::GetPtr() const
{
  pthread_key_t *pkey = (pthread_key_t *) m_KeyPointer;
  void *pdata = pthread_getspecific(pkey[0]);
  return pdata;
}

#elif defined(ITK_USE_WIN32_THREADS)

void ThreadSpecificDataSupport::Deleter(void *p)
{
}

ThreadSpecificDataSupport::ThreadSpecificDataSupport()
{
  DWORD *key = new DWORD[1];
  key[0] = TlsAlloc();
  if(key[0] == TLS_OUT_OF_INDEXES)
    throw IRISException("TlsAlloc failed with error %d", GetLastError());
  m_KeyPointer = key;
}

ThreadSpecificDataSupport::~ThreadSpecificDataSupport()
{
  DWORD *key = (DWORD *) m_KeyPointer;
  
  // Delete the stored stuff
  void *pdata = TlsGetValue(key[0]);
  if(pdata)
    free(pdata);

  TlsFree(key[0]);
  delete [] key;
}

void *ThreadSpecificDataSupport::GetPtrCreateIfNeeded(size_t data_size)
{
  DWORD *key = (DWORD *) m_KeyPointer;
  void *pdata = TlsGetValue(key[0]);

  if(!pdata)
    {
    if(GetLastError() != ERROR_SUCCESS)
      throw IRISException("TlsGetValue failed with error %d", GetLastError());

    pdata = malloc(data_size);
    if(!TlsSetValue(key[0], pdata))
      throw IRISException("TlsSetValue failed with error %d", GetLastError());
    }

  return pdata;
}

void *ThreadSpecificDataSupport::GetPtr() const
{
  DWORD *key = (DWORD *) m_KeyPointer;
  void *pdata = TlsGetValue(key[0]);
  return pdata;
}


#else

#pragma warning("No support for non-pthread threads in ITK-SNAP yet!")

#endif