@@ -46,7 +46,6 @@ int Lock_create(struct agmdb_lock *new_lock, const char* lock_name, int lock_nam
46
46
}
47
47
return AGMDB_SUCCESS_LOCK_OPEN;
48
48
}
49
-
50
49
#else
51
50
char read_lock_name[AGMDB_MAX_NAME_LEN];
52
51
char write_lock_name[AGMDB_MAX_NAME_LEN];
@@ -57,36 +56,91 @@ int Lock_create(struct agmdb_lock *new_lock, const char* lock_name, int lock_nam
57
56
return AGMDB_ERROR_LOCK_WIN_NAME_INVALID_STRING;
58
57
sprintf_s (read_lock_name, AGMDB_MAX_NAME_LEN, " DB_%s_LOCK_READ" , lock_name);
59
58
sprintf_s (write_lock_name, AGMDB_MAX_NAME_LEN, " DB_%s_LOCK_WRITE" , lock_name);
60
- new_mutex = CreateMutex (
61
- NULL , // Default security settings.
62
- FALSE , // Do not take the lock after created.
63
- read_lock_name); // The name of read lock.
64
- if (new_mutex == NULL )
59
+ new_lock-> read_lock_handle = CreateMutex (
60
+ NULL , // Default security settings.
61
+ FALSE , // Do not take the lock after created.
62
+ read_lock_name); // The name of read lock.
63
+ if (new_lock-> read_lock_handle == NULL )
65
64
return AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL;
66
65
if (GetLastError () == ERROR_ALREADY_EXISTS)
67
66
lock_exists = true ;
68
- new_lock->read_lock_handle = OpenMutex (
69
- MUTEX_ALL_ACCESS, //
70
- false , //
71
- read_lock_name);
72
67
73
- new_mutex = CreateMutex (
74
- NULL , // Default security settings.
75
- FALSE , // Do not take the lock after created.
76
- write_lock_name); // The name of write lock.
77
- if (new_mutex == NULL )
68
+ new_lock->write_lock_handle = CreateMutex (
69
+ NULL , // Default security settings.
70
+ FALSE , // Do not take the lock after created.
71
+ write_lock_name); // The name of write lock.
72
+ if (new_lock->write_lock_handle == NULL ) {
73
+ CloseHandle (new_lock->read_lock_handle );
74
+ new_lock->read_lock_handle = NULL ;
78
75
return AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL;
79
- if ((GetLastError () == ERROR_ALREADY_EXISTS) != lock_exists) // One lock exists, another not.
76
+ }
77
+
78
+ if ((GetLastError () == ERROR_ALREADY_EXISTS) != lock_exists) {
79
+ // One lock exists, another not.
80
+ CloseHandle (new_lock->read_lock_handle );
81
+ new_lock->read_lock_handle = NULL ;
82
+ CloseHandle (new_lock->write_lock_handle );
83
+ new_lock->write_lock_handle = NULL ;
80
84
return AGMDB_ERROR_LOCK_WIN_ONLY_ONE_LOCK_EXISTS;
81
- new_lock->write_lock_handle = OpenMutex (
82
- MUTEX_ALL_ACCESS, //
83
- false , //
84
- write_lock_name);
85
+ }
86
+
87
+ if (lock_exists == true )
88
+ return AGMDB_SUCCESS_LOCK_OPEN;
89
+ else
90
+ return AGMDB_SUCCESS_LOCK_CREATE;
85
91
#endif
86
92
// Should never get here
87
93
return AGMDB_SUCCESS_LOCK_CREATE;
88
94
}
89
95
96
+ /* *
97
+ ** Destroy the lock of AG Memory Database
98
+ ** @param db_lock: The agmdb_lock sturcture
99
+ ** return: AGMDB_SUCCESS if successfully destroy the lock,
100
+ ** AGMDB_ERROR if failed.
101
+ */
102
+ int Lock_destroy (struct agmdb_lock *db_lock) {
103
+ /* Windows doesn't do anything */
104
+ #ifndef _WIN32
105
+ int rc;
106
+ rc = semctl (db_lock->sem_id , 0 , IPC_RMID);
107
+ if (rc == -1 )
108
+ return AGMDB_ERROR_LOCK_LINUX_SEM_DESTROY_FAIL;
109
+ #endif
110
+ return AGMDB_SUCCESS;
111
+ }
112
+
113
+ /* *
114
+ ** Close the lock of AG Memory Database
115
+ ** @param db_lock: The agmdb_lock sturcture
116
+ ** return: AGMDB_SUCCESS if successfully close the lock,
117
+ ** AGMDB_ERROR if failed.
118
+ */
119
+ int Lock_close (struct agmdb_lock *db_lock) {
120
+ /* Linux doesn't do anything */
121
+ #ifdef _WIN32
122
+ BOOL rc_read = 1 ;
123
+ BOOL rc_write = 1 ;
124
+ if (db_lock->read_lock_handle != NULL )
125
+ {
126
+ rc_read = CloseHandle (db_lock->read_lock_handle );
127
+ if (rc_read != 0 )
128
+ db_lock->read_lock_handle = NULL ;
129
+ }
130
+
131
+ if (db_lock->write_lock_handle != NULL )
132
+ {
133
+ rc_write = CloseHandle (db_lock->write_lock_handle );
134
+ if (rc_write != 0 )
135
+ db_lock->write_lock_handle = NULL ;
136
+ }
137
+
138
+ if (rc_read == 0 || rc_write == 0 )
139
+ return AGMDB_ERROR_LOCK_WIN_CLOSE_MUTEX_FAIL;
140
+ #endif
141
+ return AGMDB_SUCCESS;
142
+ }
143
+
90
144
/* *
91
145
** Decrease a lock's value by a given number.
92
146
** @param db_lock: The agmdb_lock sturcture
@@ -236,21 +290,26 @@ int SHM_init(PTR_VOID shm_base, unsigned int shm_size, unsigned int entry_num) {
236
290
}
237
291
238
292
/* *
239
- ** Initialize the shared memory of AG Memory Database
240
- ** @param shm_base: The address of the shared memory.
293
+ ** Create the shared memory of AG Memory Database if it doesn't exist
294
+ ** Open the shared memory of AG Memory Database if it exists
295
+ ** @param dbm: The hanlder of the database.
241
296
** @param db_name: The name of the database.
242
297
** @param db_name_length: The length of db_name.
243
298
** @param entry_num: The number of entries in the shared memory.
244
299
** return: AGMDB_SUCCESS_SHM_CREATE if successfully created a new shared memory,
245
300
** AGMDB_SUCCESS_SHM_OPEN if successfully link to an existed shared memory,
246
301
** AGMDB_ERROR if failed.
247
302
*/
248
- int SHM_create (PTR_VOID* new_shm_base , const char * db_name, int db_name_length, unsigned int entry_num){
303
+ int SHM_create (struct agmdb_handler * dbm , const char * db_name, int db_name_length, unsigned int entry_num){
249
304
unsigned int shm_size = SHM_ENTRIES_OFFSET + entry_num * DEFAULT_ENTRY_SIZE;
250
305
int rc;
251
- #ifndef _WIN32
306
+ #ifndef _WIN32
252
307
int shm_id;
253
308
int shm_key;
309
+ #endif
310
+ if (dbm == NULL )
311
+ return AGMDB_ERROR_HANDLE_NULL;
312
+ #ifndef _WIN32
254
313
if (AGMDB_isstring (db_name, db_name_length) != AGMDB_SUCCESS)
255
314
return AGMDB_ERROR_SHM_NAME_INVALID_STRING;
256
315
@@ -266,8 +325,9 @@ int SHM_create(PTR_VOID* new_shm_base, const char* db_name, int db_name_length,
266
325
return AGMDB_ERROR_SHM_LINUX_CREATE_FAIL;
267
326
268
327
// Map the SHM into the address space of this process
269
- *new_shm_base = (PTR_VOID)shmat (shm_id, NULL , 0 );
270
- if (*new_shm_base == (PTR_VOID)-1 )
328
+ dbm->linux_shm_id = shm_id;
329
+ dbm->shm_base = (PTR_VOID)shmat (shm_id, NULL , 0 );
330
+ if (dbm->shm_base == (PTR_VOID)-1 )
271
331
return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
272
332
return AGMDB_SUCCESS_SHM_OPEN;
273
333
}
@@ -279,10 +339,11 @@ int SHM_create(PTR_VOID* new_shm_base, const char* db_name, int db_name_length,
279
339
}
280
340
}
281
341
else { // Map the new SHM into the address space of this process
282
- *new_shm_base = (PTR_VOID)shmat (shm_id, NULL , 0 );
283
- if (*new_shm_base == (PTR_VOID)-1 )
342
+ dbm->linux_shm_id = shm_id;
343
+ dbm->shm_base = (PTR_VOID)shmat (shm_id, NULL , 0 );
344
+ if (dbm->shm_base == (PTR_VOID)-1 )
284
345
return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
285
- rc = SHM_init (*new_shm_base , shm_size, entry_num);
346
+ rc = SHM_init ((PTR_VOID)dbm-> shm_base , shm_size, entry_num);
286
347
if (rc != AGMDB_SUCCESS)
287
348
return rc;
288
349
return AGMDB_SUCCESS_SHM_CREATE;
@@ -301,16 +362,17 @@ int SHM_create(PTR_VOID* new_shm_base, const char* db_name, int db_name_length,
301
362
db_name); // Name of shared memory.
302
363
if (shm_handle == NULL )
303
364
return AGMDB_ERROR_SHM_WIN_CREATE_FAIL;
304
- *new_shm_base = (PTR_VOID) MapViewOfFile (
365
+ dbm->win_shm_handle = shm_handle;
366
+ dbm->shm_base = (PTR_VOID) MapViewOfFile (
305
367
shm_handle, // Handle of file.
306
368
FILE_MAP_ALL_ACCESS, // All permissioon.
307
369
0 , // Map from the beginning of the shared memory.
308
370
0 , // Map from the beginning of the shared memory.
309
371
0 ); // Map entire shared memory into address space.
310
- if (new_shm_base == NULL )
372
+ if (dbm-> shm_base == NULL )
311
373
return AGMDB_ERROR_SHM_WIN_MAP_FAIL;
312
374
if (GetLastError () != ERROR_ALREADY_EXISTS) { // A new shared memory.
313
- rc = SHM_init (*new_shm_base , shm_size, entry_num);
375
+ rc = SHM_init (dbm-> shm_base , shm_size, entry_num);
314
376
if (rc != AGMDB_SUCCESS)
315
377
return rc;
316
378
return AGMDB_SUCCESS_SHM_CREATE;
@@ -321,6 +383,54 @@ int SHM_create(PTR_VOID* new_shm_base, const char* db_name, int db_name_length,
321
383
#endif
322
384
}
323
385
386
+ /* *
387
+ ** Destroy the shared memory of AG Memory Database
388
+ ** @param dbm: The handler of the database.
389
+ ** return: AGMDB_SUCCESS if successfully destroy shared memory,
390
+ ** AGMDB_ERROR if failed.
391
+ */
392
+ int SHM_destroy (struct agmdb_handler *dbm) {
393
+ int rc;
394
+ if (dbm == NULL )
395
+ return AGMDB_ERROR_HANDLE_NULL;
396
+ /* Windows doesn't do anything */
397
+ #ifndef _WIN32
398
+ rc = shmctl (dbm->linux_shm_id , IPC_RMID, 0 );
399
+ if (rc == -1 )
400
+ return AGMDB_ERROR_SHM_LINUX_DESTROY_FAIL;
401
+ #endif
402
+ return AGMDB_SUCCESS;
403
+ }
404
+
405
+ /* *
406
+ ** Close the shared memory of AG Memory Database
407
+ ** @param dbm: The handler of the database.
408
+ ** return: AGMDB_SUCCESS if successfully close shared memory,
409
+ ** AGMDB_ERROR if failed.
410
+ */
411
+ int SHM_close (struct agmdb_handler * dbm) {
412
+ #ifndef _WIN32
413
+ int rc;
414
+ #else
415
+ BOOL rc;
416
+ #endif
417
+ if (dbm == NULL )
418
+ return AGMDB_ERROR_HANDLE_NULL;
419
+ #ifndef _WIN32
420
+ rc = shmdt (dbm->shm_base );
421
+ if (rc == -1 )
422
+ return AGMDB_ERROR_SHM_LINUX_DETACH_FAIL;
423
+ #else
424
+ rc = UnmapViewOfFile (dbm->shm_base );
425
+ if (rc == -1 )
426
+ return AGMDB_ERROR_SHM_WIN_UNMAP_FAIL;
427
+ rc = CloseHandle (dbm->win_shm_handle );
428
+ if (rc == 0 )
429
+ return AGMDB_ERROR_SHM_WIN_CLOSE_HANDLE_FAIL;
430
+ #endif
431
+ return AGMDB_SUCCESS;
432
+ }
433
+
324
434
/* *
325
435
** Insert an entry into spare linklist.
326
436
** @param shm_base: The base address of shared memory.
@@ -852,16 +962,14 @@ int AGMDB_openDB(struct agmdb_handler* dbm, const char* db_name, int db_name_len
852
962
return AGMDB_ERROR_NAME_INVALID_STRING;
853
963
}
854
964
855
- rc = SHM_create (&shm_base , db_name, db_name_length , entry_num);
965
+ rc = SHM_create (dbm , db_name, db_name_length , entry_num);
856
966
if ((rc != AGMDB_SUCCESS_SHM_CREATE) && (rc != AGMDB_SUCCESS_SHM_OPEN))
857
967
return rc;
858
968
859
969
rc = Lock_create (&(dbm->db_lock ), db_name, db_name_length);
860
970
if ((rc != AGMDB_SUCCESS_LOCK_CREATE) && (rc != AGMDB_SUCCESS_LOCK_OPEN))
861
971
return rc;
862
972
863
- dbm->shm_base = shm_base;
864
-
865
973
return AGMDB_SUCCESS;
866
974
}
867
975
@@ -871,10 +979,14 @@ int AGMDB_openDB(struct agmdb_handler* dbm, const char* db_name, int db_name_len
871
979
** return: AGMDB_SUCCESS if successfully destroyed or AGMDB_ERROR if failed.
872
980
*/
873
981
int AGMDB_destroyDB (struct agmdb_handler *dbm) {
982
+ int rc;
874
983
if (dbm == NULL )
875
984
return AGMDB_ERROR_HANDLE_NULL;
876
-
877
- return AGMDB_SUCCESS;
985
+ rc = SHM_destroy (dbm);
986
+ if (rc != AGMDB_SUCCESS)
987
+ return rc;
988
+
989
+ return Lock_destroy (&(dbm->db_lock ));
878
990
}
879
991
880
992
/* *
@@ -883,10 +995,14 @@ int AGMDB_destroyDB(struct agmdb_handler *dbm) {
883
995
** return: AGMDB_SUCCESS if successfully closed or AGMDB_ERROR if failed.
884
996
*/
885
997
int AGMDB_closeDB (struct agmdb_handler *dbm) {
998
+ int rc;
886
999
if (dbm == NULL )
887
1000
return AGMDB_ERROR_HANDLE_NULL;
1001
+ rc = SHM_close (dbm);
1002
+ if (rc != AGMDB_SUCCESS)
1003
+ return rc;
888
1004
889
- return AGMDB_SUCCESS ;
1005
+ return Lock_close (&(dbm-> db_lock )) ;
890
1006
}
891
1007
892
1008
/* *
@@ -1118,7 +1234,9 @@ const char* AGMDB_getErrorInfo(int error_no){
1118
1234
return " In Linux system, failed when initializing the semaphore value. Please check the existence and permission of the semaphore." ;
1119
1235
case AGMDB_ERROR_LOCK_LINUX_SEM_MODIFY_FAIL:
1120
1236
return " In Linux system, failed when modifying the semaphore value. Please check the existence and permission of the semaphore." ;
1121
-
1237
+ case AGMDB_ERROR_LOCK_LINUX_SEM_DESTROY_FAIL:
1238
+ return " In Linux system, failed when deleting the semaphore." ;
1239
+
1122
1240
case AGMDB_ERROR_LOCK_WIN_NAME_INVALID_STRING:
1123
1241
return " In Windows system, the name of lock is not a valid string. Please check the data_dir setting in configuration file." ;
1124
1242
case AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL:
@@ -1129,6 +1247,8 @@ const char* AGMDB_getErrorInfo(int error_no){
1129
1247
return " In Windows system, failed when getting the mutex object. Possible reason is deadlock or permission issue." ;
1130
1248
case AGMDB_ERROR_LOCK_WIN_RELEASE_MUTEX_FAIL:
1131
1249
return " In Windows system, failed when releasing the mutex object." ;
1250
+ case AGMDB_ERROR_LOCK_WIN_CLOSE_MUTEX_FAIL:
1251
+ return " In Windows system, failed when close the mutex object." ;
1132
1252
1133
1253
case AGMDB_ERROR_SHM_BASE_NULL:
1134
1254
return " The shared memory base address is NULL. Please check the agmdb_handler object." ;
@@ -1147,12 +1267,20 @@ const char* AGMDB_getErrorInfo(int error_no){
1147
1267
return " In Linux system, failed when opening the shared memory." ;
1148
1268
case AGMDB_ERROR_SHM_LINUX_MAP_FAIL:
1149
1269
return " In Linux system, failed when mapping the shared memory into the process's address space." ;
1270
+ case AGMDB_ERROR_SHM_LINUX_DETACH_FAIL:
1271
+ return " In Linux system, faild when detaching the shared memory." ;
1272
+ case AGMDB_ERROR_SHM_LINUX_DESTROY_FAIL:
1273
+ return " In Linux system, faild when deleting the shared memory." ;
1150
1274
1151
1275
case AGMDB_ERROR_SHM_WIN_CREATE_FAIL:
1152
1276
return " In Windows system, failed when creating the shared memory." ;
1153
1277
case AGMDB_ERROR_SHM_WIN_MAP_FAIL:
1154
1278
return " In Windows system, failed when mapping the shared memory into the process's address space." ;
1155
-
1279
+ case AGMDB_ERROR_SHM_WIN_UNMAP_FAIL:
1280
+ return " In Windows system, faild when unmap the shared memory. Call GetLastError() for more information." ;
1281
+ case AGMDB_ERROR_SHM_WIN_CLOSE_HANDLE_FAIL:
1282
+ return " In Windows system, faild when close the shared memory handle. Call GetLastError() for more information." ;
1283
+
1156
1284
case AGMDB_ERROR_INSERT_INVALID_ENTRY_INTO_SPARELIST:
1157
1285
return " The AGMDB is inserting an invalid entry into the spare list." ;
1158
1286
case AGMDB_ERROR_INSERT_BUSY_ENTRY_INTO_SPARELIST:
0 commit comments