~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/backend/port/ipc_test.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * ipc_test.c
 
4
 *         Simplistic testbed for shared memory and semaphore code.
 
5
 *
 
6
 * This file allows for quick "smoke testing" of a PG semaphore or shared
 
7
 * memory implementation, with less overhead than compiling up a whole
 
8
 * installation.  To use:
 
9
 *      1. Run configure, then edit src/include/pg_config.h to select the
 
10
 *         USE_xxx_SEMAPHORES and USE_xxx_SHARED_MEMORY settings you want.
 
11
 *         Also, adjust the pg_sema.c and pg_shmem.c symlinks in
 
12
 *         src/backend/port/ if needed.
 
13
 *      2. In src/backend/port/, do "gmake ipc_test".
 
14
 *      3. Run ipc_test and see if it works.
 
15
 *      4. If it seems to work, try building the whole system and running
 
16
 *         the parallel regression tests for a more complete test.
 
17
 *
 
18
 *
 
19
 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
 
20
 * Portions Copyright (c) 1994, Regents of the University of California
 
21
 *
 
22
 *
 
23
 * IDENTIFICATION
 
24
 *        src/backend/port/ipc_test.c
 
25
 *
 
26
 *-------------------------------------------------------------------------
 
27
 */
 
28
#include "postgres.h"
 
29
 
 
30
#include <unistd.h>
 
31
 
 
32
#include "miscadmin.h"
 
33
#include "storage/ipc.h"
 
34
#include "storage/pg_sema.h"
 
35
#include "storage/pg_shmem.h"
 
36
 
 
37
 
 
38
/********* stuff needed to satisfy references in shmem/sema code *********/
 
39
 
 
40
 
 
41
volatile bool InterruptPending = false;
 
42
volatile bool QueryCancelPending = false;
 
43
volatile bool ProcDiePending = false;
 
44
volatile bool ImmediateInterruptOK = false;
 
45
volatile uint32 InterruptHoldoffCount = 0;
 
46
volatile uint32 CritSectionCount = 0;
 
47
 
 
48
bool            IsUnderPostmaster = false;
 
49
bool            assert_enabled = true;
 
50
 
 
51
int                     MaxBackends = 32;
 
52
int                     NBuffers = 64;
 
53
 
 
54
char       *DataDir = ".";
 
55
 
 
56
 
 
57
#define MAX_ON_EXITS 20
 
58
 
 
59
static struct ONEXIT
 
60
{
 
61
        pg_on_exit_callback function;
 
62
        Datum           arg;
 
63
}       on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
 
64
 
 
65
static int      on_proc_exit_index,
 
66
                        on_shmem_exit_index;
 
67
 
 
68
void
 
69
proc_exit(int code)
 
70
{
 
71
        shmem_exit(code);
 
72
        while (--on_proc_exit_index >= 0)
 
73
                (*on_proc_exit_list[on_proc_exit_index].function) (code,
 
74
                                                                  on_proc_exit_list[on_proc_exit_index].arg);
 
75
        exit(code);
 
76
}
 
77
 
 
78
void
 
79
shmem_exit(int code)
 
80
{
 
81
        while (--on_shmem_exit_index >= 0)
 
82
                (*on_shmem_exit_list[on_shmem_exit_index].function) (code,
 
83
                                                                on_shmem_exit_list[on_shmem_exit_index].arg);
 
84
        on_shmem_exit_index = 0;
 
85
}
 
86
 
 
87
void
 
88
on_shmem_exit(pg_on_exit_callback function, Datum arg)
 
89
{
 
90
        if (on_shmem_exit_index >= MAX_ON_EXITS)
 
91
                elog(FATAL, "out of on_shmem_exit slots");
 
92
 
 
93
        on_shmem_exit_list[on_shmem_exit_index].function = function;
 
94
        on_shmem_exit_list[on_shmem_exit_index].arg = arg;
 
95
 
 
96
        ++on_shmem_exit_index;
 
97
}
 
98
 
 
99
void
 
100
on_exit_reset(void)
 
101
{
 
102
        on_shmem_exit_index = 0;
 
103
        on_proc_exit_index = 0;
 
104
}
 
105
 
 
106
void
 
107
AddToDataDirLockFile(int target_line, const char *str)
 
108
{
 
109
}
 
110
 
 
111
void
 
112
ProcessInterrupts(void)
 
113
{
 
114
}
 
115
 
 
116
int
 
117
ExceptionalCondition(const char *conditionName,
 
118
                                         const char *errorType,
 
119
                                         const char *fileName,
 
120
                                         int lineNumber)
 
121
{
 
122
        fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
 
123
                        errorType, conditionName,
 
124
                        fileName, lineNumber);
 
125
        abort();
 
126
        return 0;
 
127
}
 
128
 
 
129
 
 
130
int
 
131
errcode_for_file_access(void)
 
132
{
 
133
        return 0;
 
134
}
 
135
 
 
136
bool
 
137
errstart(int elevel, const char *filename, int lineno,
 
138
                 const char *funcname, const char *domain)
 
139
{
 
140
        return (elevel >= ERROR);
 
141
}
 
142
 
 
143
void
 
144
errfinish(int dummy,...)
 
145
{
 
146
        proc_exit(1);
 
147
}
 
148
 
 
149
void
 
150
elog_start(const char *filename, int lineno, const char *funcname)
 
151
{
 
152
}
 
153
 
 
154
void
 
155
elog_finish(int elevel, const char *fmt,...)
 
156
{
 
157
        fprintf(stderr, "ERROR: %s\n", fmt);
 
158
        proc_exit(1);
 
159
}
 
160
 
 
161
int
 
162
errcode(int sqlerrcode)
 
163
{
 
164
        return 0;                                       /* return value does not matter */
 
165
}
 
166
 
 
167
int
 
168
errmsg(const char *fmt,...)
 
169
{
 
170
        fprintf(stderr, "ERROR: %s\n", fmt);
 
171
        return 0;                                       /* return value does not matter */
 
172
}
 
173
 
 
174
int
 
175
errmsg_internal(const char *fmt,...)
 
176
{
 
177
        fprintf(stderr, "ERROR: %s\n", fmt);
 
178
        return 0;                                       /* return value does not matter */
 
179
}
 
180
 
 
181
int
 
182
errdetail(const char *fmt,...)
 
183
{
 
184
        fprintf(stderr, "DETAIL: %s\n", fmt);
 
185
        return 0;                                       /* return value does not matter */
 
186
}
 
187
 
 
188
int
 
189
errdetail_log(const char *fmt,...)
 
190
{
 
191
        fprintf(stderr, "DETAIL: %s\n", fmt);
 
192
        return 0;                                       /* return value does not matter */
 
193
}
 
194
 
 
195
int
 
196
errhint(const char *fmt,...)
 
197
{
 
198
        fprintf(stderr, "HINT: %s\n", fmt);
 
199
        return 0;                                       /* return value does not matter */
 
200
}
 
201
 
 
202
 
 
203
/********* here's the actual test *********/
 
204
 
 
205
 
 
206
typedef struct MyStorage
 
207
{
 
208
        PGShmemHeader header;
 
209
        int                     flag;
 
210
        PGSemaphoreData sem;
 
211
}       MyStorage;
 
212
 
 
213
 
 
214
int
 
215
main(int argc, char **argv)
 
216
{
 
217
        MyStorage  *storage;
 
218
        int                     cpid;
 
219
 
 
220
        printf("Creating shared memory ... ");
 
221
        fflush(stdout);
 
222
 
 
223
        storage = (MyStorage *) PGSharedMemoryCreate(8192, false, 5433);
 
224
 
 
225
        storage->flag = 1234;
 
226
 
 
227
        printf("OK\n");
 
228
 
 
229
        printf("Creating semaphores ... ");
 
230
        fflush(stdout);
 
231
 
 
232
        PGReserveSemaphores(2, 5433);
 
233
 
 
234
        PGSemaphoreCreate(&storage->sem);
 
235
 
 
236
        printf("OK\n");
 
237
 
 
238
        /* sema initial value is 1, so lock should work */
 
239
 
 
240
        printf("Testing Lock ... ");
 
241
        fflush(stdout);
 
242
 
 
243
        PGSemaphoreLock(&storage->sem, false);
 
244
 
 
245
        printf("OK\n");
 
246
 
 
247
        /* now sema value is 0, so trylock should fail */
 
248
 
 
249
        printf("Testing TryLock ... ");
 
250
        fflush(stdout);
 
251
 
 
252
        if (PGSemaphoreTryLock(&storage->sem))
 
253
                printf("unexpected result!\n");
 
254
        else
 
255
                printf("OK\n");
 
256
 
 
257
        /* unlocking twice and then locking twice should work... */
 
258
 
 
259
        printf("Testing Multiple Lock ... ");
 
260
        fflush(stdout);
 
261
 
 
262
        PGSemaphoreUnlock(&storage->sem);
 
263
        PGSemaphoreUnlock(&storage->sem);
 
264
 
 
265
        PGSemaphoreLock(&storage->sem, false);
 
266
        PGSemaphoreLock(&storage->sem, false);
 
267
 
 
268
        printf("OK\n");
 
269
 
 
270
        /* check Reset too */
 
271
 
 
272
        printf("Testing Reset ... ");
 
273
        fflush(stdout);
 
274
 
 
275
        PGSemaphoreUnlock(&storage->sem);
 
276
 
 
277
        PGSemaphoreReset(&storage->sem);
 
278
 
 
279
        if (PGSemaphoreTryLock(&storage->sem))
 
280
                printf("unexpected result!\n");
 
281
        else
 
282
                printf("OK\n");
 
283
 
 
284
        /* Fork a child process and see if it can communicate */
 
285
 
 
286
        printf("Forking child process ... ");
 
287
        fflush(stdout);
 
288
 
 
289
        cpid = fork();
 
290
        if (cpid == 0)
 
291
        {
 
292
                /* In child */
 
293
                on_exit_reset();
 
294
                sleep(3);
 
295
                storage->flag++;
 
296
                PGSemaphoreUnlock(&storage->sem);
 
297
                proc_exit(0);
 
298
        }
 
299
        if (cpid < 0)
 
300
        {
 
301
                /* Fork failed */
 
302
                printf("failed: %s\n", strerror(errno));
 
303
                proc_exit(1);
 
304
        }
 
305
 
 
306
        printf("forked child pid %d OK\n", cpid);
 
307
 
 
308
        if (storage->flag != 1234)
 
309
                printf("Wrong value found in shared memory!\n");
 
310
 
 
311
        printf("Waiting for child (should wait 3 sec here) ... ");
 
312
        fflush(stdout);
 
313
 
 
314
        PGSemaphoreLock(&storage->sem, false);
 
315
 
 
316
        printf("OK\n");
 
317
 
 
318
        if (storage->flag != 1235)
 
319
                printf("Wrong value found in shared memory!\n");
 
320
 
 
321
        /* Test shutdown */
 
322
 
 
323
        printf("Running shmem_exit processing ... ");
 
324
        fflush(stdout);
 
325
 
 
326
        shmem_exit(0);
 
327
 
 
328
        printf("OK\n");
 
329
 
 
330
        printf("Tests complete.\n");
 
331
 
 
332
        proc_exit(0);
 
333
 
 
334
        return 0;                                       /* not reached */
 
335
}