Skip to content

Commit 9aa6755

Browse files
committed
Rewrite SHM_create(), SHM_close(), and SHM_destroy().
1 parent 24bd90d commit 9aa6755

File tree

1 file changed

+106
-55
lines changed

1 file changed

+106
-55
lines changed

apache2/ag_mdb/ag_mdb.cpp

Lines changed: 106 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
*/
303303
int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_length, unsigned int entry_num) {
304304
unsigned int shm_size = SHM_ENTRIES_OFFSET + entry_num * DEFAULT_ENTRY_SIZE;
305305
int rc;
306306
#ifndef _WIN32
307307
int shm_id;
308308
int shm_key;
309+
#else
310+
bool shm_is_create = true;
309311
#endif
310312
if (dbm == NULL)
311313
return 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);
331335
return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
336+
}
332337
return AGMDB_SUCCESS_SHM_OPEN;
333338
}
334339
else if (errno == EACCES) {
@@ -341,40 +346,61 @@ int SHM_create(struct agmdb_handler* dbm, const char* db_name, int db_name_lengt
341346
else { // 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);
345352
return 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);
348357
return rc;
358+
}
349359
return AGMDB_SUCCESS_SHM_CREATE;
350360
}
351361
#else
352-
HANDLE shm_handle;
353362
if (AGMDB_isstring(db_name, db_name_length) != AGMDB_SUCCESS)
354363
return 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.
358367
NULL, // Defaut security setting.
359368
PAGE_READWRITE, // Read and Write permission.
360369
0, // 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;
364374
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+
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.
369384
0, // Map from the beginning of the shared memory.
370385
0, // Map from the beginning of the shared memory.
371386
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);
373392
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);
377402
return rc;
403+
}
378404
return AGMDB_SUCCESS_SHM_CREATE;
379405
}
380406
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
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+
*/
392418
int SHM_destroy(struct agmdb_handler *dbm) {
393419
int rc;
394420
if (dbm == NULL)
395421
return 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
402434
return 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+
*/
411443
int 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
417450
if (dbm == NULL)
418451
return 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+
*/
948999
int AGMDB_openDB(struct agmdb_handler* dbm, const char* db_name, int db_name_length, unsigned int entry_num) {
9491000
int rc;
9501001
PTR_VOID shm_base;

0 commit comments

Comments
 (0)