00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "postgres.h"
00029
00030 #include <unistd.h>
00031
00032 #include "miscadmin.h"
00033 #include "storage/ipc.h"
00034 #include "storage/pg_sema.h"
00035 #include "storage/pg_shmem.h"
00036
00037
00038
00039
00040
00041 volatile bool InterruptPending = false;
00042 volatile bool QueryCancelPending = false;
00043 volatile bool ProcDiePending = false;
00044 volatile bool ImmediateInterruptOK = false;
00045 volatile uint32 InterruptHoldoffCount = 0;
00046 volatile uint32 CritSectionCount = 0;
00047
00048 bool IsUnderPostmaster = false;
00049 bool assert_enabled = true;
00050
00051 int MaxBackends = 32;
00052 int NBuffers = 64;
00053
00054 char *DataDir = ".";
00055
00056
00057 #define MAX_ON_EXITS 20
00058
00059 static struct ONEXIT
00060 {
00061 pg_on_exit_callback function;
00062 Datum arg;
00063 } on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS];
00064
00065 static int on_proc_exit_index,
00066 on_shmem_exit_index;
00067
00068 void
00069 proc_exit(int code)
00070 {
00071 shmem_exit(code);
00072 while (--on_proc_exit_index >= 0)
00073 (*on_proc_exit_list[on_proc_exit_index].function) (code,
00074 on_proc_exit_list[on_proc_exit_index].arg);
00075 exit(code);
00076 }
00077
00078 void
00079 shmem_exit(int code)
00080 {
00081 while (--on_shmem_exit_index >= 0)
00082 (*on_shmem_exit_list[on_shmem_exit_index].function) (code,
00083 on_shmem_exit_list[on_shmem_exit_index].arg);
00084 on_shmem_exit_index = 0;
00085 }
00086
00087 void
00088 on_shmem_exit(pg_on_exit_callback function, Datum arg)
00089 {
00090 if (on_shmem_exit_index >= MAX_ON_EXITS)
00091 elog(FATAL, "out of on_shmem_exit slots");
00092
00093 on_shmem_exit_list[on_shmem_exit_index].function = function;
00094 on_shmem_exit_list[on_shmem_exit_index].arg = arg;
00095
00096 ++on_shmem_exit_index;
00097 }
00098
00099 void
00100 on_exit_reset(void)
00101 {
00102 on_shmem_exit_index = 0;
00103 on_proc_exit_index = 0;
00104 }
00105
00106 void
00107 AddToDataDirLockFile(int target_line, const char *str)
00108 {
00109 }
00110
00111 void
00112 ProcessInterrupts(void)
00113 {
00114 }
00115
00116 void
00117 ExceptionalCondition(const char *conditionName,
00118 const char *errorType,
00119 const char *fileName,
00120 int lineNumber)
00121 {
00122 fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
00123 errorType, conditionName,
00124 fileName, lineNumber);
00125 abort();
00126 }
00127
00128
00129 int
00130 errcode_for_file_access(void)
00131 {
00132 return 0;
00133 }
00134
00135 bool
00136 errstart(int elevel, const char *filename, int lineno,
00137 const char *funcname, const char *domain)
00138 {
00139 return (elevel >= ERROR);
00140 }
00141
00142 void
00143 errfinish(int dummy,...)
00144 {
00145 proc_exit(1);
00146 }
00147
00148 void
00149 elog_start(const char *filename, int lineno, const char *funcname)
00150 {
00151 }
00152
00153 void
00154 elog_finish(int elevel, const char *fmt,...)
00155 {
00156 fprintf(stderr, "ERROR: %s\n", fmt);
00157 proc_exit(1);
00158 }
00159
00160 int
00161 errcode(int sqlerrcode)
00162 {
00163 return 0;
00164 }
00165
00166 int
00167 errmsg(const char *fmt,...)
00168 {
00169 fprintf(stderr, "ERROR: %s\n", fmt);
00170 return 0;
00171 }
00172
00173 int
00174 errmsg_internal(const char *fmt,...)
00175 {
00176 fprintf(stderr, "ERROR: %s\n", fmt);
00177 return 0;
00178 }
00179
00180 int
00181 errdetail(const char *fmt,...)
00182 {
00183 fprintf(stderr, "DETAIL: %s\n", fmt);
00184 return 0;
00185 }
00186
00187 int
00188 errdetail_log(const char *fmt,...)
00189 {
00190 fprintf(stderr, "DETAIL: %s\n", fmt);
00191 return 0;
00192 }
00193
00194 int
00195 errhint(const char *fmt,...)
00196 {
00197 fprintf(stderr, "HINT: %s\n", fmt);
00198 return 0;
00199 }
00200
00201
00202
00203
00204
00205 typedef struct MyStorage
00206 {
00207 PGShmemHeader header;
00208 int flag;
00209 PGSemaphoreData sem;
00210 } MyStorage;
00211
00212
00213 int
00214 main(int argc, char **argv)
00215 {
00216 MyStorage *storage;
00217 int cpid;
00218
00219 printf("Creating shared memory ... ");
00220 fflush(stdout);
00221
00222 storage = (MyStorage *) PGSharedMemoryCreate(8192, false, 5433);
00223
00224 storage->flag = 1234;
00225
00226 printf("OK\n");
00227
00228 printf("Creating semaphores ... ");
00229 fflush(stdout);
00230
00231 PGReserveSemaphores(2, 5433);
00232
00233 PGSemaphoreCreate(&storage->sem);
00234
00235 printf("OK\n");
00236
00237
00238
00239 printf("Testing Lock ... ");
00240 fflush(stdout);
00241
00242 PGSemaphoreLock(&storage->sem, false);
00243
00244 printf("OK\n");
00245
00246
00247
00248 printf("Testing TryLock ... ");
00249 fflush(stdout);
00250
00251 if (PGSemaphoreTryLock(&storage->sem))
00252 printf("unexpected result!\n");
00253 else
00254 printf("OK\n");
00255
00256
00257
00258 printf("Testing Multiple Lock ... ");
00259 fflush(stdout);
00260
00261 PGSemaphoreUnlock(&storage->sem);
00262 PGSemaphoreUnlock(&storage->sem);
00263
00264 PGSemaphoreLock(&storage->sem, false);
00265 PGSemaphoreLock(&storage->sem, false);
00266
00267 printf("OK\n");
00268
00269
00270
00271 printf("Testing Reset ... ");
00272 fflush(stdout);
00273
00274 PGSemaphoreUnlock(&storage->sem);
00275
00276 PGSemaphoreReset(&storage->sem);
00277
00278 if (PGSemaphoreTryLock(&storage->sem))
00279 printf("unexpected result!\n");
00280 else
00281 printf("OK\n");
00282
00283
00284
00285 printf("Forking child process ... ");
00286 fflush(stdout);
00287
00288 cpid = fork();
00289 if (cpid == 0)
00290 {
00291
00292 on_exit_reset();
00293 sleep(3);
00294 storage->flag++;
00295 PGSemaphoreUnlock(&storage->sem);
00296 proc_exit(0);
00297 }
00298 if (cpid < 0)
00299 {
00300
00301 printf("failed: %s\n", strerror(errno));
00302 proc_exit(1);
00303 }
00304
00305 printf("forked child PID %d OK\n", cpid);
00306
00307 if (storage->flag != 1234)
00308 printf("Wrong value found in shared memory!\n");
00309
00310 printf("Waiting for child (should wait 3 sec here) ... ");
00311 fflush(stdout);
00312
00313 PGSemaphoreLock(&storage->sem, false);
00314
00315 printf("OK\n");
00316
00317 if (storage->flag != 1235)
00318 printf("Wrong value found in shared memory!\n");
00319
00320
00321
00322 printf("Running shmem_exit processing ... ");
00323 fflush(stdout);
00324
00325 shmem_exit(0);
00326
00327 printf("OK\n");
00328
00329 printf("Tests complete.\n");
00330
00331 proc_exit(0);
00332
00333 return 0;
00334 }