1 /*------------------------------------------------------------------------------
2 * Copyright (C) 2003-2006 Ben van Klinken and the CLucene Team
3 *
4 * Distributable under the terms of either the Apache License (Version 2.0) or
5 * the GNU Lesser General Public License, as specified in the COPYING file.
6 ------------------------------------------------------------------------------*/
7 #include "CLucene/_ApiHeader.h"
8 #include "Lock.h"
9 #include "_Lock.h"
10 #include "CLucene/util/Misc.h"
11
12 #ifdef _CL_HAVE_IO_H
13 #include <io.h>
14 #endif
15 #ifdef _CL_HAVE_SYS_STAT_H
16 #include <sys/stat.h>
17 #endif
18 #ifdef _CL_HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif
21 #ifdef _CL_HAVE_DIRECT_H
22 #include <direct.h>
23 #endif
24 #include <fcntl.h>
25
26
27 CL_NS_USE(util)
CL_NS_DEF(store)28 CL_NS_DEF(store)
29
30 LuceneLock::~LuceneLock()
31 {
32 }
obtain(int64_t lockWaitTimeout)33 bool LuceneLock::obtain(int64_t lockWaitTimeout) {
34 bool locked = obtain();
35 if ( lockWaitTimeout < 0 && lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER ) {
36 _CLTHROWA(CL_ERR_IllegalArgument,"lockWaitTimeout should be LOCK_OBTAIN_WAIT_FOREVER or a non-negative number");
37 }
38
39 int64_t maxSleepCount = lockWaitTimeout / LOCK_POLL_INTERVAL;
40 int64_t sleepCount = 0;
41
42 while (!locked) {
43 if ( lockWaitTimeout != LOCK_OBTAIN_WAIT_FOREVER && sleepCount++ == maxSleepCount ) {
44 _CLTHROWA(CL_ERR_IO,"Lock obtain timed out");
45 }
46 _LUCENE_SLEEP(LOCK_POLL_INTERVAL);
47 locked = obtain();
48 }
49
50 return locked;
51 }
toString()52 std::string NoLock::toString()
53 {
54 return "NoLock";
55 }
obtain()56 bool NoLock::obtain() { return true; }
release()57 void NoLock::release() {}
isLocked()58 bool NoLock::isLocked() { return false; }
59
getClassName()60 const char* NoLock::getClassName(){
61 return "NoLock";
62 }
getObjectName() const63 const char* NoLock::getObjectName() const{
64 return getClassName();
65 }
66
67
68
SingleInstanceLock(LocksType * locks,_LUCENE_THREADMUTEX * locks_LOCK,const char * lockName)69 SingleInstanceLock::SingleInstanceLock( LocksType* locks, _LUCENE_THREADMUTEX* locks_LOCK, const char* lockName )
70 {
71 this->locks = locks;
72 #ifndef _CL_DISABLE_MULTITHREADING
73 this->locks_LOCK = locks_LOCK;
74 #endif
75 this->lockName = lockName;
76 }
~SingleInstanceLock()77 SingleInstanceLock::~SingleInstanceLock(){
78 }
getClassName()79 const char* SingleInstanceLock::getClassName(){
80 return "SingleInstanceLock";
81 }
getObjectName() const82 const char* SingleInstanceLock::getObjectName() const{
83 return getClassName();
84 }
85
obtain()86 bool SingleInstanceLock::obtain()
87 {
88 SCOPED_LOCK_MUTEX(*locks_LOCK);
89 return locks->insert( lockName ).second;
90 }
91
release()92 void SingleInstanceLock::release()
93 {
94 SCOPED_LOCK_MUTEX(*locks_LOCK);
95 LocksType::iterator itr = locks->find( lockName );
96 if ( itr != locks->end() ) {
97 locks->remove(itr, true);
98 }
99 }
100
isLocked()101 bool SingleInstanceLock::isLocked()
102 {
103 SCOPED_LOCK_MUTEX(*locks_LOCK);
104 return locks->find( lockName ) == locks->end();
105 }
106
toString()107 string SingleInstanceLock::toString()
108 {
109 return string("SingleInstanceLock:") + lockName;
110 }
111
112
FSLock(const char * _lockDir,const char * name,int filemode)113 FSLock::FSLock( const char* _lockDir, const char* name, int filemode )
114 {
115 if ( filemode <= 0 )
116 this->filemode = 0644; //must do this or file will be created Read only
117 else
118 this->filemode = filemode;
119
120 this->lockFile = _CL_NEWARRAY(char,CL_MAX_PATH);
121 this->lockDir = STRDUP_AtoA(_lockDir);
122 strcpy(lockFile,_lockDir);
123 strcat(lockFile,PATH_DELIMITERA);
124 strcat(lockFile,name);
125 }
126
~FSLock()127 FSLock::~FSLock()
128 {
129 _CLDELETE_ARRAY( lockFile );
130 _CLDELETE_LCaARRAY( lockDir );
131 }
132
getClassName()133 const char* FSLock::getClassName(){
134 return "FSLock";
135 }
getObjectName() const136 const char* FSLock::getObjectName() const{
137 return getClassName();
138 }
139
obtain()140 bool FSLock::obtain()
141 {
142 if ( !Misc::dir_Exists(lockDir) ){
143 if ( _mkdir(lockDir) == -1 ){
144 char* err = _CL_NEWARRAY(char,34+strlen(lockDir)+1); //34: len of "Couldn't create lock directory: "
145 strcpy(err,"Couldn't create lock directory: ");
146 strcat(err,lockDir);
147 _CLTHROWA_DEL(CL_ERR_IO, err );
148 }
149 }
150 int32_t r = _cl_open(lockFile, O_RDWR | O_CREAT | _O_RANDOM | O_EXCL, this->filemode);
151 if ( r < 0 ) {
152 return false;
153 } else {
154 _close(r);
155 return true;
156 }
157 }
158
release()159 void FSLock::release()
160 {
161 _unlink( lockFile );
162 }
163
isLocked()164 bool FSLock::isLocked()
165 {
166 return Misc::dir_Exists(lockFile);
167 }
168
toString()169 string FSLock::toString()
170 {
171 return string("SimpleFSLock@") + lockFile;
172 }
173
174 CL_NS_END
175