@@ -290,22 +290,24 @@ int SHM_init(PTR_VOID shm_base, unsigned int shm_size, unsigned int entry_num) {
290290}
291291
292292/* *
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+ */
303303int SHM_create (struct agmdb_handler * dbm,const char * db_name,int db_name_length,unsigned int entry_num) {
304304unsigned int shm_size = SHM_ENTRIES_OFFSET + entry_num * DEFAULT_ENTRY_SIZE;
305305int rc;
306306#ifndef _WIN32
307307int shm_id;
308308int shm_key;
309+ #else
310+ bool shm_is_create =true ;
309311#endif
310312if (dbm ==NULL )
311313return AGMDB_ERROR_HANDLE_NULL;
@@ -327,8 +329,11 @@ int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_lengt
327329// Map the SHM into the address space of this process
328330 dbm->linux_shm_id = shm_id;
329331 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);
331335return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
336+ }
332337return AGMDB_SUCCESS_SHM_OPEN;
333338 }
334339else if (errno == EACCES) {
@@ -341,40 +346,61 @@ int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_lengt
341346else {// Map the new SHM into the address space of this process
342347 dbm->linux_shm_id = shm_id;
343348 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);
345352return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
353+ }
346354 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);
348357return rc;
358+ }
349359return AGMDB_SUCCESS_SHM_CREATE;
350360 }
351361#else
352- HANDLE shm_handle;
353362if (AGMDB_isstring (db_name, db_name_length) != AGMDB_SUCCESS)
354363return AGMDB_ERROR_SHM_NAME_INVALID_STRING;
355364
356- shm_handle =CreateFileMapping (
365+ dbm-> win_shm_handle =CreateFileMapping (
357366 INVALID_HANDLE_VALUE,// A memory, not a real file.
358367NULL ,// Defaut security setting.
359368 PAGE_READWRITE,// Read and Write permission.
3603690 ,// High 32-bit of shm size.
361370 shm_size,// Low 32-bit of shm size.
362371 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;
364374return 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+
366381 dbm->shm_base = (PTR_VOID)MapViewOfFile (
367- shm_handle, // Handle of file.
382+ dbm-> win_shm_handle , // Handle of file.
368383 FILE_MAP_ALL_ACCESS,// All permissioon.
3693840 ,// Map from the beginning of the shared memory.
3703850 ,// Map from the beginning of the shared memory.
3713860 );// 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);
373392return 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);
377402return rc;
403+ }
378404return AGMDB_SUCCESS_SHM_CREATE;
379405 }
380406else {// 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
384410}
385411
386412/* *
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+ */
392418int SHM_destroy (struct agmdb_handler *dbm) {
393419int rc;
394420if (dbm ==NULL )
395421return AGMDB_ERROR_HANDLE_NULL;
422+ rc =SHM_close (dbm);
423+ if (AGMDB_isError (rc))
424+ return rc;
396425/* Windows doesn't do anything*/
397426#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+ }
401433#endif
402434return AGMDB_SUCCESS;
403435}
404436
405437/* *
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+ */
411443int SHM_close (struct agmdb_handler * dbm) {
412444#ifndef _WIN32
413- int rc;
445+ int rc = 0 ;
414446#else
415- BOOL rc;
447+ BOOL rc =0 ;
448+ int ret_win = AGMDB_SUCCESS;
416449#endif
417450if (dbm ==NULL )
418451return AGMDB_ERROR_HANDLE_NULL;
419452#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;
423460#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;
430482#endif
431- return AGMDB_SUCCESS;
432483}
433484
434485/* *
@@ -937,14 +988,14 @@ inline int AGMDB_deleteEntry(CPTR_VOID shm_base, PTR_OFFSET entry_id) {
937988}
938989
939990/* *
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+ */
948999int AGMDB_openDB (struct agmdb_handler * dbm,const char * db_name,int db_name_length,unsigned int entry_num) {
9491000int rc;
9501001 PTR_VOID shm_base;