2121int Lock_create (struct agmdb_lock *new_lock,const char * lock_name,int lock_name_length) {
2222#ifndef _WIN32
2323union semun sem_union;
24- int lock_id =AGMDB_hash (lock_name, lock_name_length, DEFAULT_AGMDB_ID_RANGE);
24+ int lock_id = -1 ;
25+ #else
26+ int read_lock_name_len =0 ;
27+ int write_lock_name_len =0 ;
28+ char * read_lock_name =NULL ;
29+ char * write_lock_name =NULL ;
30+ bool lock_exists =false ;
31+ #endif
32+ if (new_lock ==NULL )
33+ return AGMDB_ERROR_HANDLE_NULL;
34+ #ifndef _WIN32
35+ lock_id =AGMDB_hash (lock_name, lock_name_length, DEFAULT_AGMDB_ID_RANGE);
2536 new_lock->sem_id =semget (lock_id, SEM_NUMBERS, IPC_CREAT | IPC_EXCL);
2637if (new_lock->sem_id != -1 ) {
2738// A new semaphore set is created, need to initialize the semaphore set
2839 sem_union.val = SEM_READ_INITVAL;
2940if (semctl (new_lock->sem_id , SEM_ID_READ, SETVAL, sem_union) == -1 ) {
41+ Lock_destroy (new_lock);
3042return AGMDB_ERROR_LOCK_LINUX_SEM_CREATE_FAIL;
3143 }
3244
3345 sem_union.val = SEM_WRITE_INITVAL;
3446if (semctl (new_lock->sem_id , SEM_ID_WRITE, SETVAL, sem_union) == -1 ) {
35- // If failed, reset the read lock
36- sem_union.val =0 ;
37- semctl (new_lock->sem_id , SEM_ID_READ, SETVAL, sem_union);
47+ // If failed, destroy the lock
48+ Lock_destroy (new_lock);
3849return AGMDB_ERROR_LOCK_LINUX_SEM_INIT_FAIL;
3950 }
4051return AGMDB_SUCCESS_LOCK_CREATE;
@@ -47,39 +58,49 @@ int Lock_create(struct agmdb_lock *new_lock, const char* lock_name, int lock_nam
4758return AGMDB_SUCCESS_LOCK_OPEN;
4859 }
4960#else
50- char read_lock_name[AGMDB_MAX_NAME_LEN];
51- char write_lock_name[AGMDB_MAX_NAME_LEN];
52- bool lock_exists =false ;
61+ read_lock_name_len = (strlen (READ_LOCK_PREFIX) +strlen (lock_name) +1 ) *sizeof (char );
62+ write_lock_name_len = (strlen (WRITE_LOCK_PREFIX) +strlen (lock_name) +1 ) *sizeof (char );
5363
5464if (AGMDB_isstring (lock_name, lock_name_length) != AGMDB_SUCCESS)
5565return AGMDB_ERROR_LOCK_WIN_NAME_INVALID_STRING;
56- sprintf_s (read_lock_name, AGMDB_MAX_NAME_LEN," DB_%s_LOCK_READ" , lock_name);
57- sprintf_s (write_lock_name, AGMDB_MAX_NAME_LEN," DB_%s_LOCK_WRITE" , lock_name);
66+
67+ read_lock_name = (char *)malloc (read_lock_name_len *sizeof (char ));
68+ sprintf_s (read_lock_name, read_lock_name_len," %s%s" , READ_LOCK_PREFIX, lock_name);
5869 new_lock->read_lock_handle =CreateMutex (
5970NULL ,// Default security settings.
6071FALSE ,// Do not take the lock after created.
6172 read_lock_name);// The name of read lock.
62- if (new_lock->read_lock_handle ==NULL )
73+ free (read_lock_name);
74+
75+ if (new_lock->read_lock_handle ==NULL ) {
76+ new_lock->read_lock_handle = INVALID_HANDLE_VALUE;
6377return AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL;
78+ }
79+
6480if (GetLastError () == ERROR_ALREADY_EXISTS)
6581 lock_exists =true ;
6682
83+ write_lock_name = (char *)malloc (write_lock_name_len *sizeof (char ));
84+ sprintf_s (write_lock_name, write_lock_name_len," %s%s" , WRITE_LOCK_PREFIX, lock_name);
6785 new_lock->write_lock_handle =CreateMutex (
6886NULL ,// Default security settings.
6987FALSE ,// Do not take the lock after created.
7088 write_lock_name);// The name of write lock.
89+ free (write_lock_name);
90+
7191if (new_lock->write_lock_handle ==NULL ) {
7292CloseHandle (new_lock->read_lock_handle );
73- new_lock->read_lock_handle =NULL ;
93+ new_lock->read_lock_handle = INVALID_HANDLE_VALUE;
94+ new_lock->write_lock_handle = INVALID_HANDLE_VALUE;
7495return AGMDB_ERROR_LOCK_WIN_MUTEX_CREATE_FAIL;
7596 }
7697
7798if ((GetLastError () == ERROR_ALREADY_EXISTS) != lock_exists) {
7899// One lock exists, another not.
79100CloseHandle (new_lock->read_lock_handle );
80- new_lock->read_lock_handle =NULL ;
101+ new_lock->read_lock_handle =INVALID_HANDLE_VALUE ;
81102CloseHandle (new_lock->write_lock_handle );
82- new_lock->write_lock_handle =NULL ;
103+ new_lock->write_lock_handle =INVALID_HANDLE_VALUE ;
83104return AGMDB_ERROR_LOCK_WIN_ONLY_ONE_LOCK_EXISTS;
84105 }
85106
@@ -99,14 +120,23 @@ int Lock_create(struct agmdb_lock *new_lock, const char* lock_name, int lock_nam
99120** AGMDB_ERROR if failed.
100121*/
101122int Lock_destroy (struct agmdb_lock *db_lock) {
102- /* Windows doesn't do anything*/
123+ int rc = AGMDB_SUCCESS;
124+ if (db_lock ==NULL )
125+ return AGMDB_ERROR_HANDLE_NULL;
126+ rc =Lock_close (db_lock);
127+ if (AGMDB_isError (rc))
128+ return rc;
103129#ifndef _WIN32
104- int rc;
105130 rc =semctl (db_lock->sem_id ,0 , IPC_RMID);
106131if (rc == -1 )
107132return AGMDB_ERROR_LOCK_LINUX_SEM_DESTROY_FAIL;
108- #endif
133+ else
134+ db_lock->sem_id = -1 ;
109135return AGMDB_SUCCESS;
136+ #else
137+ /* Locks destroy doesn't support on Windows*/
138+ return AGMDB_ERROR_LOCK_WIN_DESTROY_NOT_SUPPORT;
139+ #endif
110140}
111141
112142/* *
@@ -116,22 +146,24 @@ int Lock_destroy(struct agmdb_lock *db_lock) {
116146** AGMDB_ERROR if failed.
117147*/
118148int Lock_close (struct agmdb_lock *db_lock) {
149+ if (db_lock ==NULL )
150+ return AGMDB_ERROR_HANDLE_NULL;
119151/* Linux doesn't do anything*/
120152#ifdef _WIN32
121153 BOOL rc_read =1 ;
122154 BOOL rc_write =1 ;
123- if (db_lock->read_lock_handle !=NULL )
155+ if (db_lock->read_lock_handle !=INVALID_HANDLE_VALUE )
124156 {
125157 rc_read =CloseHandle (db_lock->read_lock_handle );
126158if (rc_read !=0 )
127- db_lock->read_lock_handle =NULL ;
159+ db_lock->read_lock_handle =INVALID_HANDLE_VALUE ;
128160 }
129161
130- if (db_lock->write_lock_handle !=NULL )
162+ if (db_lock->write_lock_handle !=INVALID_HANDLE_VALUE )
131163 {
132164 rc_write =CloseHandle (db_lock->write_lock_handle );
133165if (rc_write !=0 )
134- db_lock->write_lock_handle =NULL ;
166+ db_lock->write_lock_handle =INVALID_HANDLE_VALUE ;
135167 }
136168
137169if (rc_read ==0 || rc_write ==0 )
@@ -421,16 +453,19 @@ int SHM_destroy(struct agmdb_handler *dbm) {
421453 rc =SHM_close (dbm);
422454if (AGMDB_isError (rc))
423455return rc;
424- /* Windows doesn't do anything */
456+
425457#ifndef _WIN32
426458if (dbm->linux_shm_id != -1 ) {
427459 rc =shmctl (dbm->linux_shm_id , IPC_RMID,0 );
428460if (rc == -1 )
429461return AGMDB_ERROR_SHM_LINUX_DESTROY_FAIL;
430462 dbm->linux_shm_id = -1 ;
431463 }
432- #endif
433464return AGMDB_SUCCESS;
465+ #else
466+ /* Shared memory destroy doesn't support on Windows*/
467+ return AGMDB_ERROR_SHM_WIN_DESTROY_NOT_SUPPORT;
468+ #endif
434469}
435470
436471/* *
@@ -895,10 +930,10 @@ int AGMDB_freeExclusiveLock(struct agmdb_handler *dbm) {
895930
896931 rc =Lock_V (db_lock, SEM_ID_READ, SEM_READ_INITVAL);
897932if (rc != AGMDB_SUCCESS)
898- return AGMDB_ERROR ;
933+ return rc ;
899934 rc =Lock_V (db_lock, SEM_ID_WRITE,1 );
900935if (rc != AGMDB_SUCCESS)
901- return AGMDB_ERROR ;
936+ return rc ;
902937
903938return AGMDB_SUCCESS;
904939}
@@ -1094,6 +1129,11 @@ int AGMDB_destroyDB(struct agmdb_handler *dbm) {
10941129
10951130 rc_shm =SHM_destroy (dbm);
10961131 rc_lock =Lock_destroy (&(dbm->db_lock ));
1132+
1133+ /* Database destroy doesn't support on Windows*/
1134+ if (rc_shm == AGMDB_ERROR_SHM_WIN_DESTROY_NOT_SUPPORT && rc_lock == AGMDB_ERROR_LOCK_WIN_DESTROY_NOT_SUPPORT)
1135+ return AGMDB_ERROR_DB_WIN_DESTROY_NOT_SUPPORT;
1136+
10971137if (AGMDB_isError (rc_shm))
10981138return rc_shm;
10991139else if (AGMDB_isError (rc_lock))
@@ -1412,6 +1452,9 @@ const char* AGMDB_getErrorInfo(int error_no) {
14121452case AGMDB_ERROR_GETALL_ARRAY_TOO_SMALL:
14131453return " In getAll function, the array is too samll to save the data." ;
14141454
1455+ case AGMDB_ERROR_DB_WIN_DESTROY_NOT_SUPPORT:
1456+ return " In Windows system, the destroy operation doesn't supported. Just close the database." ;
1457+
14151458case AGMDB_ERROR_UNEXPECTED:
14161459return " Unexpected error happens." ;
14171460
@@ -1447,6 +1490,8 @@ const char* AGMDB_getErrorInfo(int error_no) {
14471490return " In Windows system, faild when close the shared memory handle. Call GetLastError() for more information." ;
14481491case AGMDB_ERROR_SHM_WIN_UNMAP_AND_CLOSE_HANDLE_FAIL:
14491492return " In Windows system, faild when unmap the shared memory and close the shared memory handle. Call GetLastError() for more information." ;
1493+ case AGMDB_ERROR_SHM_WIN_DESTROY_NOT_SUPPORT:
1494+ return " In Windows system, the shared memory destroy operation doesn't supported. Just close the shared memory." ;
14501495
14511496case AGMDB_ERROR_LOCK_OP_NEGATIVE_VAL:
14521497return " When operating the lock, the operation value is negative!" ;
@@ -1474,6 +1519,8 @@ const char* AGMDB_getErrorInfo(int error_no) {
14741519return " In Windows system, failed when releasing the mutex object." ;
14751520case AGMDB_ERROR_LOCK_WIN_CLOSE_MUTEX_FAIL:
14761521return " In Windows system, failed when close the mutex object." ;
1522+ case AGMDB_ERROR_LOCK_WIN_DESTROY_NOT_SUPPORT:
1523+ return " In Windows system, the lock destroy operation doesn't supported. Just close the locks." ;
14771524
14781525default :
14791526return " Error code is not found." ;