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