Skip to content

Commit fb6c2ec

Browse files
committed
Rewrite Lock_create(), Lock_destroy(), and Lock_close() for Lock operation. Rewrite SHM_create(), SHM_destroy(), and SHM_close() for Shared Memory operation. Rewrite AGMDB_openDB(), AGMDB_destroyDB(), and AGMDB_closeDB().
1 parent 0518409 commit fb6c2ec

File tree

3 files changed

+222
-50
lines changed

3 files changed

+222
-50
lines changed

apache2/ag_mdb/ag_mdb.cpp

Lines changed: 168 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ int Lock_create(struct agmdb_lock *new_lock, const char* lock_name, int lock_nam
4646
}
4747
return AGMDB_SUCCESS_LOCK_OPEN;
4848
}
49-
5049
#else
5150
char read_lock_name[AGMDB_MAX_NAME_LEN];
5251
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
5756
return AGMDB_ERROR_LOCK_WIN_NAME_INVALID_STRING;
5857
sprintf_s(read_lock_name, AGMDB_MAX_NAME_LEN, "DB_%s_LOCK_READ", lock_name);
5958
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)
6564
return AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL;
6665
if(GetLastError() == ERROR_ALREADY_EXISTS)
6766
lock_exists = true;
68-
new_lock->read_lock_handle = OpenMutex(
69-
MUTEX_ALL_ACCESS, //
70-
false, //
71-
read_lock_name);
7267

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;
7875
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;
8084
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;
8591
#endif
8692
// Should never get here
8793
return AGMDB_SUCCESS_LOCK_CREATE;
8894
}
8995

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+
90144
/**
91145
** Decrease a lock's value by a given number.
92146
** @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) {
236290
}
237291

238292
/**
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.
241296
** @param db_name: The name of the database.
242297
** @param db_name_length: The length of db_name.
243298
** @param entry_num: The number of entries in the shared memory.
244299
** return: AGMDB_SUCCESS_SHM_CREATE if successfully created a new shared memory,
245300
** AGMDB_SUCCESS_SHM_OPEN if successfully link to an existed shared memory,
246301
** AGMDB_ERROR if failed.
247302
*/
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){
249304
unsigned int shm_size = SHM_ENTRIES_OFFSET + entry_num * DEFAULT_ENTRY_SIZE;
250305
int rc;
251-
#ifndef _WIN32
306+
#ifndef _WIN32
252307
int shm_id;
253308
int shm_key;
309+
#endif
310+
if(dbm == NULL)
311+
return AGMDB_ERROR_HANDLE_NULL;
312+
#ifndef _WIN32
254313
if (AGMDB_isstring(db_name, db_name_length) != AGMDB_SUCCESS)
255314
return AGMDB_ERROR_SHM_NAME_INVALID_STRING;
256315

@@ -266,8 +325,9 @@ int SHM_create(PTR_VOID* new_shm_base, const char* db_name, int db_name_length,
266325
return AGMDB_ERROR_SHM_LINUX_CREATE_FAIL;
267326

268327
// 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)
271331
return AGMDB_ERROR_SHM_LINUX_MAP_FAIL;
272332
return AGMDB_SUCCESS_SHM_OPEN;
273333
}
@@ -279,10 +339,11 @@ int SHM_create(PTR_VOID* new_shm_base, const char* db_name, int db_name_length,
279339
}
280340
}
281341
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)
284345
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);
286347
if(rc != AGMDB_SUCCESS)
287348
return rc;
288349
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,
301362
db_name); // Name of shared memory.
302363
if(shm_handle == NULL)
303364
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(
305367
shm_handle, // Handle of file.
306368
FILE_MAP_ALL_ACCESS, // All permissioon.
307369
0, // Map from the beginning of the shared memory.
308370
0, // Map from the beginning of the shared memory.
309371
0); // Map entire shared memory into address space.
310-
if(new_shm_base == NULL)
372+
if(dbm->shm_base == NULL)
311373
return AGMDB_ERROR_SHM_WIN_MAP_FAIL;
312374
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);
314376
if(rc != AGMDB_SUCCESS)
315377
return rc;
316378
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,
321383
#endif
322384
}
323385

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+
324434
/**
325435
** Insert an entry into spare linklist.
326436
** @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
852962
return AGMDB_ERROR_NAME_INVALID_STRING;
853963
}
854964

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);
856966
if((rc != AGMDB_SUCCESS_SHM_CREATE) && (rc != AGMDB_SUCCESS_SHM_OPEN))
857967
return rc;
858968

859969
rc = Lock_create(&(dbm->db_lock), db_name, db_name_length);
860970
if((rc != AGMDB_SUCCESS_LOCK_CREATE) && (rc != AGMDB_SUCCESS_LOCK_OPEN))
861971
return rc;
862972

863-
dbm->shm_base = shm_base;
864-
865973
return AGMDB_SUCCESS;
866974
}
867975

@@ -871,10 +979,14 @@ int AGMDB_openDB(struct agmdb_handler* dbm, const char* db_name, int db_name_len
871979
** return: AGMDB_SUCCESS if successfully destroyed or AGMDB_ERROR if failed.
872980
*/
873981
int AGMDB_destroyDB(struct agmdb_handler *dbm) {
982+
int rc;
874983
if(dbm == NULL)
875984
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));
878990
}
879991

880992
/**
@@ -883,10 +995,14 @@ int AGMDB_destroyDB(struct agmdb_handler *dbm) {
883995
** return: AGMDB_SUCCESS if successfully closed or AGMDB_ERROR if failed.
884996
*/
885997
int AGMDB_closeDB(struct agmdb_handler *dbm) {
998+
int rc;
886999
if(dbm == NULL)
8871000
return AGMDB_ERROR_HANDLE_NULL;
1001+
rc = SHM_close(dbm);
1002+
if(rc != AGMDB_SUCCESS)
1003+
return rc;
8881004

889-
return AGMDB_SUCCESS;
1005+
return Lock_close(&(dbm->db_lock));
8901006
}
8911007

8921008
/**
@@ -1118,7 +1234,9 @@ const char* AGMDB_getErrorInfo(int error_no){
11181234
return "In Linux system, failed when initializing the semaphore value. Please check the existence and permission of the semaphore.";
11191235
case AGMDB_ERROR_LOCK_LINUX_SEM_MODIFY_FAIL:
11201236
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+
11221240
case AGMDB_ERROR_LOCK_WIN_NAME_INVALID_STRING:
11231241
return "In Windows system, the name of lock is not a valid string. Please check the data_dir setting in configuration file.";
11241242
case AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL:
@@ -1129,6 +1247,8 @@ const char* AGMDB_getErrorInfo(int error_no){
11291247
return "In Windows system, failed when getting the mutex object. Possible reason is deadlock or permission issue.";
11301248
case AGMDB_ERROR_LOCK_WIN_RELEASE_MUTEX_FAIL:
11311249
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.";
11321252

11331253
case AGMDB_ERROR_SHM_BASE_NULL:
11341254
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){
11471267
return "In Linux system, failed when opening the shared memory.";
11481268
case AGMDB_ERROR_SHM_LINUX_MAP_FAIL:
11491269
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.";
11501274

11511275
case AGMDB_ERROR_SHM_WIN_CREATE_FAIL:
11521276
return "In Windows system, failed when creating the shared memory.";
11531277
case AGMDB_ERROR_SHM_WIN_MAP_FAIL:
11541278
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+
11561284
case AGMDB_ERROR_INSERT_INVALID_ENTRY_INTO_SPARELIST:
11571285
return "The AGMDB is inserting an invalid entry into the spare list.";
11581286
case AGMDB_ERROR_INSERT_BUSY_ENTRY_INTO_SPARELIST:

apache2/ag_mdb/ag_mdb_external.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@ extern "C" {
3838
#define AGMDB_ERROR_LOCK_LINUX_SEM_OPEN_FAIL 10101
3939
#define AGMDB_ERROR_LOCK_LINUX_SEM_INIT_FAIL 10102
4040
#define AGMDB_ERROR_LOCK_LINUX_SEM_MODIFY_FAIL 10103
41+
#define AGMDB_ERROR_LOCK_LINUX_SEM_DESTROY_FAIL 10104
4142

4243
#define AGMDB_ERROR_LOCK_WIN_NAME_INVALID_STRING 10200
4344
#define AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL 10201
4445
#define AGMDB_ERROR_LOCK_WIN_ONLY_ONE_LOCK_EXISTS 10202
4546
#define AGMDB_ERROR_LOCK_WIN_GET_MUTEX_FAIL 10203
4647
#define AGMDB_ERROR_LOCK_WIN_RELEASE_MUTEX_FAIL 10204
48+
#define AGMDB_ERROR_LOCK_WIN_CLOSE_MUTEX_FAIL 10205
4749

4850
#define AGMDB_ERROR_SHM_BASE_NULL 11000
4951
#define AGMDB_ERROR_SHM_SIZE_TOO_SMALL 11001
@@ -54,9 +56,13 @@ extern "C" {
5456
#define AGMDB_ERROR_SHM_LINUX_OPEN_FAIL 11101
5557
#define AGMDB_ERROR_SHM_LINUX_OPEN_ACCESS_FAIL 11102
5658
#define AGMDB_ERROR_SHM_LINUX_MAP_FAIL 11103
59+
#define AGMDB_ERROR_SHM_LINUX_DETACH_FAIL 11104
60+
#define AGMDB_ERROR_SHM_LINUX_DESTROY_FAIL 11105
5761

5862
#define AGMDB_ERROR_SHM_WIN_CREATE_FAIL 11200
5963
#define AGMDB_ERROR_SHM_WIN_MAP_FAIL 11201
64+
#define AGMDB_ERROR_SHM_WIN_UNMAP_FAIL 11202
65+
#define AGMDB_ERROR_SHM_WIN_CLOSE_HANDLE_FAIL 11203
6066

6167
#define AGMDB_ERROR_INSERT_INVALID_ENTRY_INTO_SPARELIST 12000
6268
#define AGMDB_ERROR_INSERT_BUSY_ENTRY_INTO_SPARELIST 12001
@@ -123,6 +129,11 @@ struct agmdb_lock{
123129
struct agmdb_handler{
124130
const void* shm_base;
125131
struct agmdb_lock db_lock;
132+
#ifndef _WIN32
133+
int linux_shm_id;
134+
#else
135+
HANDLE win_shm_handle;
136+
#endif
126137
};
127138

128139
/**

0 commit comments

Comments
 (0)