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,12 +120,19 @@ 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) {
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;
102129/* Windows doesn't do anything*/
103130#ifndef _WIN32
104- int rc;
105131 rc =semctl (db_lock->sem_id ,0 , IPC_RMID);
106132if (rc == -1 )
107133return AGMDB_ERROR_LOCK_LINUX_SEM_DESTROY_FAIL;
134+ else
135+ db_lock->sem_id = -1 ;
108136#endif
109137return AGMDB_SUCCESS;
110138}
@@ -116,22 +144,24 @@ int Lock_destroy(struct agmdb_lock *db_lock) {
116144** AGMDB_ERROR if failed.
117145*/
118146int Lock_close (struct agmdb_lock *db_lock) {
147+ if (db_lock ==NULL )
148+ return AGMDB_ERROR_HANDLE_NULL;
119149/* Linux doesn't do anything*/
120150#ifdef _WIN32
121151 BOOL rc_read =1 ;
122152 BOOL rc_write =1 ;
123- if (db_lock->read_lock_handle !=NULL )
153+ if (db_lock->read_lock_handle !=INVALID_HANDLE_VALUE )
124154 {
125155 rc_read =CloseHandle (db_lock->read_lock_handle );
126156if (rc_read !=0 )
127- db_lock->read_lock_handle =NULL ;
157+ db_lock->read_lock_handle =INVALID_HANDLE_VALUE ;
128158 }
129159
130- if (db_lock->write_lock_handle !=NULL )
160+ if (db_lock->write_lock_handle !=INVALID_HANDLE_VALUE )
131161 {
132162 rc_write =CloseHandle (db_lock->write_lock_handle );
133163if (rc_write !=0 )
134- db_lock->write_lock_handle =NULL ;
164+ db_lock->write_lock_handle =INVALID_HANDLE_VALUE ;
135165 }
136166
137167if (rc_read ==0 || rc_write ==0 )