@@ -290,22 +290,24 @@ int SHM_init(PTR_VOID shm_base, unsigned int shm_size, unsigned int entry_num) {
290
290
}
291
291
292
292
/* *
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.
296
- ** @param db_name: The name of the database.
297
- ** @param db_name_length: The length of db_name.
298
- ** @param entry_num: The number of entries in the shared memory.
299
- ** return: AGMDB_SUCCESS_SHM_CREATE if successfully created a new shared memory,
300
- ** AGMDB_SUCCESS_SHM_OPEN if successfully link to an existed shared memory,
301
- ** AGMDB_ERROR if failed.
302
- */
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.
296
+ ** @param db_name: The name of the database.
297
+ ** @param db_name_length: The length of db_name.
298
+ ** @param entry_num: The number of entries in the shared memory.
299
+ ** return: AGMDB_SUCCESS_SHM_CREATE if successfully created a new shared memory,
300
+ ** AGMDB_SUCCESS_SHM_OPEN if successfully link to an existed shared memory,
301
+ ** AGMDB_ERROR if failed.
302
+ */
303
303
int SHM_create (struct agmdb_handler * dbm, const char * db_name, int db_name_length, unsigned int entry_num) {
304
304
unsigned int shm_size = SHM_ENTRIES_OFFSET + entry_num * DEFAULT_ENTRY_SIZE;
305
305
int rc;
306
306
#ifndef _WIN32
307
307
int shm_id;
308
308
int shm_key;
309
+ #else
310
+ bool shm_is_create = true ;
309
311
#endif
310
312
if (dbm == NULL )
311
313
return AGMDB_ERROR_HANDLE_NULL;
@@ -327,8 +329,11 @@ int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_lengt
327
329
// Map the SHM into the address space of this process
328
330
dbm->linux_shm_id = shm_id;
329
331
dbm->shm_base = (PTR_VOID)shmat (shm_id, NULL , 0 );
330
- if (dbm->shm_base == (PTR_VOID)-1 )
332
+ if (dbm->shm_base == (PTR_VOID)-1 ) {
333
+ dbm->shm_base = NULL ;
334
+ SHM_close (dbm);
331
335
return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
336
+ }
332
337
return AGMDB_SUCCESS_SHM_OPEN;
333
338
}
334
339
else if (errno == EACCES) {
@@ -341,40 +346,61 @@ int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_lengt
341
346
else { // Map the new SHM into the address space of this process
342
347
dbm->linux_shm_id = shm_id;
343
348
dbm->shm_base = (PTR_VOID)shmat (shm_id, NULL , 0 );
344
- if (dbm->shm_base == (PTR_VOID)-1 )
349
+ if (dbm->shm_base == (PTR_VOID)-1 ) {
350
+ dbm->shm_base = NULL ;
351
+ SHM_destroy (dbm);
345
352
return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
353
+ }
346
354
rc = SHM_init ((PTR_VOID)dbm->shm_base , shm_size, entry_num);
347
- if (rc != AGMDB_SUCCESS)
355
+ if (rc != AGMDB_SUCCESS) {
356
+ SHM_destroy (dbm);
348
357
return rc;
358
+ }
349
359
return AGMDB_SUCCESS_SHM_CREATE;
350
360
}
351
361
#else
352
- HANDLE shm_handle;
353
362
if (AGMDB_isstring (db_name, db_name_length) != AGMDB_SUCCESS)
354
363
return AGMDB_ERROR_SHM_NAME_INVALID_STRING;
355
364
356
- shm_handle = CreateFileMapping (
365
+ dbm-> win_shm_handle = CreateFileMapping (
357
366
INVALID_HANDLE_VALUE, // A memory, not a real file.
358
367
NULL , // Defaut security setting.
359
368
PAGE_READWRITE, // Read and Write permission.
360
369
0 , // High 32-bit of shm size.
361
370
shm_size, // Low 32-bit of shm size.
362
371
db_name); // Name of shared memory.
363
- if (shm_handle == NULL )
372
+ if (dbm->win_shm_handle == NULL ) {
373
+ dbm->win_shm_handle = INVALID_HANDLE_VALUE;
364
374
return AGMDB_ERROR_SHM_WIN_CREATE_FAIL;
365
- dbm->win_shm_handle = shm_handle;
375
+ }
376
+ else if (GetLastError () == ERROR_ALREADY_EXISTS) {
377
+ // Existing Shared Memory
378
+ shm_is_create = false ;
379
+ }
380
+
366
381
dbm->shm_base = (PTR_VOID)MapViewOfFile (
367
- shm_handle, // Handle of file.
382
+ dbm-> win_shm_handle , // Handle of file.
368
383
FILE_MAP_ALL_ACCESS, // All permissioon.
369
384
0 , // Map from the beginning of the shared memory.
370
385
0 , // Map from the beginning of the shared memory.
371
386
0 ); // Map entire shared memory into address space.
372
- if (dbm->shm_base == NULL )
387
+ if (dbm->shm_base == NULL ) {
388
+ if (shm_is_create)
389
+ SHM_destroy (dbm);
390
+ else
391
+ SHM_close (dbm);
373
392
return AGMDB_ERROR_SHM_WIN_MAP_FAIL;
374
- if (GetLastError () != ERROR_ALREADY_EXISTS) { // A new shared memory.
375
- rc = SHM_init (dbm->shm_base , shm_size, entry_num);
376
- if (rc != AGMDB_SUCCESS)
393
+ }
394
+
395
+ if (shm_is_create) { // A New Shared Memory
396
+ rc = SHM_init ((PTR_VOID)dbm->shm_base , shm_size, entry_num);
397
+ if (rc != AGMDB_SUCCESS) {
398
+ if (shm_is_create)
399
+ SHM_destroy (dbm);
400
+ else
401
+ SHM_close (dbm);
377
402
return rc;
403
+ }
378
404
return AGMDB_SUCCESS_SHM_CREATE;
379
405
}
380
406
else { // There has been a SHM with the given name
@@ -384,51 +410,76 @@ int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_lengt
384
410
}
385
411
386
412
/* *
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
- */
413
+ ** Destroy the shared memory of AG Memory Database
414
+ ** @param dbm: The handler of the database.
415
+ ** return: AGMDB_SUCCESS if successfully destroy shared memory,
416
+ ** AGMDB_ERROR if failed.
417
+ */
392
418
int SHM_destroy (struct agmdb_handler *dbm) {
393
419
int rc;
394
420
if (dbm == NULL )
395
421
return AGMDB_ERROR_HANDLE_NULL;
422
+ rc = SHM_close (dbm);
423
+ if (AGMDB_isError (rc))
424
+ return rc;
396
425
/* Windows doesn't do anything */
397
426
#ifndef _WIN32
398
- rc = shmctl (dbm->linux_shm_id , IPC_RMID, 0 );
399
- if (rc == -1 )
400
- return AGMDB_ERROR_SHM_LINUX_DESTROY_FAIL;
427
+ if (dbm->linux_shm_id != -1 ) {
428
+ rc = shmctl (dbm->linux_shm_id , IPC_RMID, 0 );
429
+ if (rc == -1 )
430
+ return AGMDB_ERROR_SHM_LINUX_DESTROY_FAIL;
431
+ dbm->linux_shm_id = -1 ;
432
+ }
401
433
#endif
402
434
return AGMDB_SUCCESS;
403
435
}
404
436
405
437
/* *
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
- */
438
+ ** Close the shared memory of AG Memory Database
439
+ ** @param dbm: The handler of the database.
440
+ ** return: AGMDB_SUCCESS if successfully close shared memory,
441
+ ** AGMDB_ERROR if failed.
442
+ */
411
443
int SHM_close (struct agmdb_handler * dbm) {
412
444
#ifndef _WIN32
413
- int rc;
445
+ int rc = 0 ;
414
446
#else
415
- BOOL rc;
447
+ BOOL rc = 0 ;
448
+ int ret_win = AGMDB_SUCCESS;
416
449
#endif
417
450
if (dbm == NULL )
418
451
return AGMDB_ERROR_HANDLE_NULL;
419
452
#ifndef _WIN32
420
- rc = shmdt (dbm->shm_base );
421
- if (rc == -1 )
422
- return AGMDB_ERROR_SHM_LINUX_DETACH_FAIL;
453
+ if (dbm->shm_base != NULL ) {
454
+ rc = shmdt (dbm->shm_base );
455
+ if (rc == -1 )
456
+ return AGMDB_ERROR_SHM_LINUX_DETACH_FAIL;
457
+ dbm->shm_base = NULL ;
458
+ }
459
+ return AGMDB_SUCCESS;
423
460
#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;
461
+ if (dbm->shm_base != NULL ) {
462
+ rc = UnmapViewOfFile (dbm->shm_base );
463
+ if (rc == 0 )
464
+ ret_win = AGMDB_ERROR_SHM_WIN_UNMAP_FAIL;
465
+ else
466
+ dbm->shm_base = NULL ;
467
+ }
468
+
469
+ if (dbm->win_shm_handle != INVALID_HANDLE_VALUE) {
470
+ rc = CloseHandle (dbm->win_shm_handle );
471
+ if (rc == 0 ) {
472
+ if (ret_win == AGMDB_ERROR_SHM_WIN_UNMAP_FAIL)
473
+ ret_win = AGMDB_ERROR_SHM_WIN_UNMAP_AND_CLOSE_HANDLE_FAIL;
474
+ else
475
+ ret_win = AGMDB_ERROR_SHM_WIN_CLOSE_HANDLE_FAIL;
476
+ }
477
+ else {
478
+ dbm->win_shm_handle = INVALID_HANDLE_VALUE;
479
+ }
480
+ }
481
+ return ret_win;
430
482
#endif
431
- return AGMDB_SUCCESS;
432
483
}
433
484
434
485
/* *
@@ -937,14 +988,14 @@ inline int AGMDB_deleteEntry(CPTR_VOID shm_base, PTR_OFFSET entry_id) {
937
988
}
938
989
939
990
/* *
940
- ** Open a database with given name, and intialize the agmdb handler for further operation.
941
- ** If the database doesn't exist, a new database will be created.
942
- ** @param dbm: a created sturcture to save the database information.
943
- ** @param db_name: the unique identifier of a database.
944
- ** @param db_name_length: the length of the unique_name.
945
- ** @param entry_num: The maximum number of entries in the database.
946
- ** return: AGMDB_SUCCESS if successfully created or AGMDB_ERROR if failed.
947
- */
991
+ ** Open a database with given name, and intialize the agmdb handler for further operation.
992
+ ** If the database doesn't exist, a new database will be created.
993
+ ** @param dbm: a created sturcture to save the database information.
994
+ ** @param db_name: the unique identifier of a database.
995
+ ** @param db_name_length: the length of the unique_name.
996
+ ** @param entry_num: The maximum number of entries in the database.
997
+ ** return: AGMDB_SUCCESS if successfully created or AGMDB_ERROR if failed.
998
+ */
948
999
int AGMDB_openDB (struct agmdb_handler * dbm, const char * db_name, int db_name_length, unsigned int entry_num) {
949
1000
int rc;
950
1001
PTR_VOID shm_base;
0 commit comments