summaryrefslogtreecommitdiff
path: root/src/mt/lock.cc
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
committerHenrik Rydberg <rydberg@euromail.se>2011-10-08 20:30:28 +0200
commit5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch)
tree1a81af141708b826e9c61e8a04019994fcca8298 /src/mt/lock.cc
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
Diffstat (limited to 'src/mt/lock.cc')
-rw-r--r--src/mt/lock.cc114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/mt/lock.cc b/src/mt/lock.cc
new file mode 100644
index 0000000..5b72967
--- /dev/null
+++ b/src/mt/lock.cc
@@ -0,0 +1,114 @@
1/*************************************************************************
2 *
3 * HTCd - Copyright (C) 1998-2006 Henrik Rydberg
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <mt/lock.h>
21#include <unistd.h>
22#include <fcntl.h>
23#include <errno.h>
24#include <sys/utsname.h>
25#include <signal.h>
26using namespace std;
27
28const mstring LOCK=".lock";
29
30void LockFile(const mstring& path,int prot) throw(merror_t)
31{
32 mstring name=path+LOCK; int fd;
33 while((fd=open(name.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot))==-1&&
34 errno==EEXIST) sleep(1);
35 if(fd<0) THROW("lock: could not create lock file "<<name);
36 close(fd);
37}
38
39int remove(const char* path);
40void UnlockFile(const mstring& path)
41{
42 remove((path+LOCK).c_str());
43}
44
45///////////////////////////////////////////////////////////////////
46
47proclock_t::proclock_t(const mstring& p,int prot) : pid(0),path(p+LOCK)
48{
49 mstring buf,name=path;
50 int fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot);
51 if(fd<0) {
52 if(errno==EEXIST) {
53 buf.load(path);
54 int oldpid=atoi(buf);
55 if(kill(oldpid,0)==0) THROW("proclock: already running as "<<buf)
56 else fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC,prot);
57 }
58 else THROW("proclock: could not create lock file "<<path);
59 }
60 pid=getpid();
61 buf.convert("%d",pid);
62 write(fd,buf.data(),buf.size());
63 close(fd);
64}
65
66proclock_t::~proclock_t()
67{
68 if(getpid()==pid) remove(path.c_str());
69}
70
71///////////////////////////////////////////////////////////////////
72
73nodelock_t::nodelock_t(const mstring& p,int prot) : pid(0),path(p+LOCK)
74{
75 struct utsname uts; uname(&uts);
76 mstring buf;
77 int fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot);
78 if(fd<0) {
79 if(errno==EEXIST) {
80 if(buf.load(path)>=0) {
81 if(buf.nempty()&&buf!=sref(uts.nodename))
82 THROW("nodelock: already locked on "<<buf);
83 }
84 else {
85 fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC,prot);
86 pid=getpid();
87 buf=uts.nodename;
88 write(fd,buf.data(),buf.size());
89 close(fd);
90 }
91 }
92 else THROW("nodelock: could not create lock file "<<path);
93 }
94 else {
95 pid=getpid();
96 buf=uts.nodename;
97 write(fd,buf.data(),buf.size());
98 close(fd);
99 }
100}
101
102nodelock_t::~nodelock_t()
103{
104 if(getpid()==pid) remove(path.c_str());
105}
106
107///////////////////////////////////////////////////////////////////
108
109void ProcTerminate(const mstring& p,int stime)
110{
111 mstring buf,path=p+LOCK;
112 if(buf.load(path)>=0) while(!kill(atoi(buf),SIGTERM)) sleep(stime);
113}
114