summaryrefslogtreecommitdiff
path: root/ACE/tests/Bug_2980_Regression_Test.cpp
blob: 002cf03b53c2c514366ee8ca552e29fd25e4d22d (plain)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
//FUZZ: disable check_for_lack_ACE_OS

#include "ace/config-lite.h"

#include <iostream>
#include <assert.h>
#include <cstdio>
#include <string.h>
#include <stdlib.h>
#include <string.h>

// This is a non-ACE driver program which loads an ACE-based DLL.  The
// usual ACE-related defines will not apply and we must use
// platform-specific ones.
//
// This test has not been made to work on Windows and vxWorks, yet ...
#if defined (ACE_HAS_THREADS)
#  define CAN_USE_THREADS
#else
#  undef CAN_USE_THREADS
#endif

#if !(defined (WIN32) || defined (ACE_VXWORKS) || defined (ACE_HAS_LYNXOS_178))\
    && !defined ACE_FACE_SAFETY_EXTENDED
#  define CAN_RUN_TEST

#  include <dlfcn.h>

namespace {
#  if defined (ACE_DLL_SUFFIX)
  const char *DllTestName = "./libBug_2980_Regression" ACE_DLL_SUFFIX;
#else
  const char *DllTestName = "./libBug_2980_Regression.so";
#endif /* ACE_DLL_SUFFIX */
}

#  if defined CAN_USE_THREADS
#    include <pthread.h>
#  endif

#else
#  undef CAN_RUN_TEST
#endif

using voidfunction = int (*)();

#if defined (CAN_RUN_TEST)
static void * dllHandle;
static voidfunction   capi_init = 0;
static voidfunction   capi_fini = 0;
static voidfunction   capi_dosomething = 0;
#endif /* defined (CAN_RUN_TEST) */

extern "C"
void* loadDll(void*)
{
#if defined (CAN_RUN_TEST)
  std::printf ("loadDll - entered\n");
  const char *subdir_env = getenv ("ACE_EXE_SUB_DIR");
  if (subdir_env)
    {
      char *dllFile =
        (char *) malloc (2 + strlen (subdir_env) + strlen (DllTestName));
      strcpy (dllFile, subdir_env);
      strcat (dllFile, "/");
      strcat (dllFile, DllTestName);
      dllHandle = dlopen (dllFile, RTLD_NOW);
      free (dllFile);
    }
  else
    {
      dllHandle = dlopen (DllTestName, RTLD_NOW);
    }

  if (dllHandle == 0)
  {
    std::printf ("unable to load library: %s\n", dlerror());
    assert(dllHandle != 0);
  }

  void* temp = dlsym (dllHandle, "capi_init");
  memcpy (&capi_init, &temp, sizeof (temp));
  if (capi_init == 0)
  {
    std::printf ("unable to resolve symbol capi_init: %s\n", dlerror());
    assert(capi_init != 0);
  }

  temp = dlsym (dllHandle, "capi_fini");
  memcpy (&capi_fini, &temp, sizeof (temp));
  if (capi_fini == 0)
  {
    std::printf ("unable to resolve symbol capi_fini: %s\n", dlerror());
    assert(capi_fini != 0);
  }

  temp = dlsym (dllHandle, "capi_dosomething");
  memcpy (&capi_dosomething, &temp, sizeof (temp));
  if (capi_dosomething == 0)
  {
    std::printf ("unable to resolve symbol capi_dosomething: %s\n", dlerror());
    assert(capi_dosomething != 0);
  }
  capi_init();
  std::printf ("loadDll - leaving\n");
#endif /* defined (CAN_RUN_TEST) */
  return 0;
}

extern "C"
void* unloadDll(void*)
{
#if defined (CAN_RUN_TEST)
  std::printf ("unloadDll - entered\n");
  capi_fini();
  dlclose(dllHandle);
  std::printf ("unloadDll - leaving\n");
#endif /* defined (CAN_RUN_TEST) */
  return 0;
}

void * loadunloadDll(void *pp)
{
  loadDll(pp);

#if defined (CAN_RUN_TEST)
  assert(capi_dosomething != 0);
  capi_dosomething();
#endif /* defined (CAN_RUN_TEST) */

  unloadDll(pp);

  return 0;
}
// FUZZ: disable check_for_improper_main_declaration
int main (int, char *[])
{
#if !defined (CAN_RUN_TEST)
# ifndef ACE_FACE_SAFETY_EXTENDED
  std::printf ("Terminating because this test has not been designed "
          "to run on WIN32 or VXWORKS.\n");
# endif
#else
  std::printf ("main called\n");
  std::printf ("main - calling loadDll\n");

#  if defined (CAN_USE_THREADS)
  int result = 0;
  pthread_t tid1;
  result = pthread_create(&tid1, 0, &loadDll, 0);
  if (result != 0)
  {
    std::printf ("pthread_create() failed: %d\n", result);
    return result;
  }

  pthread_join(tid1, 0);
  std::printf ("loadDll thread finished and re-joined\n");

#  else

  loadDll(0);
  std::printf ("loadDll finished\n");

#  endif /* defined (CAN_USE_THREADS) */

  std::printf ("main - calling unloadDll\n");

#  if defined (CAN_USE_THREADS)
  pthread_t tid2;
  result = pthread_create(&tid2, 0, &unloadDll, 0);
  if (result != 0)
  {
    std::printf ("pthread_create() failed: %d\n", result);
    return 1;
  }
  pthread_join(tid2, 0);
  std::printf ("unloadDll thread finished and re-joined\n");

#  else

  unloadDll(0);
  std::printf ("unloadDll finished\n");

#  endif /* defined (CAN_USE_THREADS) */

  std::printf ("main finished\n");
#endif /* defined (CAN_RUN_TEST) */

  return 0;
}
//FUZZ: enable check_for_lack_ACE_OS