source: box/trunk/lib/common/NamedLock.cpp @ 2536

Revision 2536, 3.5 KB checked in by chris, 3 years ago (diff)

Make NamedLock? take a std::string instead of a char pointer for C++
style.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    NamedLock.cpp
5//              Purpose: A global named lock, implemented as a lock file in
6//                       file system
7//              Created: 2003/08/28
8//
9// --------------------------------------------------------------------------
10
11#include "Box.h"
12
13#include <fcntl.h>
14#include <errno.h>
15
16#ifdef HAVE_UNISTD_H
17        #include <unistd.h>
18#endif
19
20#ifdef HAVE_FLOCK
21        #include <sys/file.h>
22#endif
23
24#include "NamedLock.h"
25#include "CommonException.h"
26
27#include "MemLeakFindOn.h"
28
29// --------------------------------------------------------------------------
30//
31// Function
32//              Name:    NamedLock::NamedLock()
33//              Purpose: Constructor
34//              Created: 2003/08/28
35//
36// --------------------------------------------------------------------------
37NamedLock::NamedLock()
38        : mFileDescriptor(-1)
39{
40}
41
42// --------------------------------------------------------------------------
43//
44// Function
45//              Name:    NamedLock::~NamedLock()
46//              Purpose: Destructor (automatically unlocks if locked)
47//              Created: 2003/08/28
48//
49// --------------------------------------------------------------------------
50NamedLock::~NamedLock()
51{
52        if(mFileDescriptor != -1)
53        {
54                ReleaseLock();
55        }
56}
57
58// --------------------------------------------------------------------------
59//
60// Function
61//              Name:    NamedLock::TryAndGetLock(const char *, int)
62//              Purpose: Tries to get a lock on the name in the file system.
63//                       IMPORTANT NOTE: If a file exists with this name, it
64//                       will be deleted.
65//              Created: 2003/08/28
66//
67// --------------------------------------------------------------------------
68bool NamedLock::TryAndGetLock(const std::string& rFilename, int mode)
69{
70        // Check
71        if(mFileDescriptor != -1)
72        {
73                THROW_EXCEPTION(CommonException, NamedLockAlreadyLockingSomething)
74        }
75
76        // See if the lock can be got
77#if HAVE_DECL_O_EXLOCK
78        int fd = ::open(rFilename.c_str(),
79                O_WRONLY | O_NONBLOCK | O_CREAT | O_TRUNC | O_EXLOCK, mode);
80        if(fd != -1)
81        {
82                // Got a lock, lovely
83                mFileDescriptor = fd;
84                return true;
85        }
86       
87        // Failed. Why?
88        if(errno != EWOULDBLOCK)
89        {
90                // Not the expected error
91                THROW_EXCEPTION(CommonException, OSFileError)
92        }
93
94        return false;
95#else
96        int fd = ::open(rFilename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, mode);
97        if(fd == -1)
98        {
99                BOX_WARNING("Failed to open lockfile: " << rFilename);
100                THROW_EXCEPTION(CommonException, OSFileError)
101        }
102
103#ifdef HAVE_FLOCK
104        if(::flock(fd, LOCK_EX | LOCK_NB) != 0)
105        {
106                ::close(fd);
107                if(errno == EWOULDBLOCK)
108                {
109                        return false;
110                }
111                else
112                {
113                        THROW_EXCEPTION(CommonException, OSFileError)
114                }
115        }
116#elif HAVE_DECL_F_SETLK
117        struct flock desc;
118        desc.l_type = F_WRLCK;
119        desc.l_whence = SEEK_SET;
120        desc.l_start = 0;
121        desc.l_len = 0;
122        if(::fcntl(fd, F_SETLK, &desc) != 0)
123        {
124                ::close(fd);
125                if(errno == EAGAIN)
126                {
127                        return false;
128                }
129                else
130                {
131                        THROW_EXCEPTION(CommonException, OSFileError)
132                }
133        }
134#endif
135
136        // Success
137        mFileDescriptor = fd;
138
139        return true;
140#endif
141}
142
143// --------------------------------------------------------------------------
144//
145// Function
146//              Name:    NamedLock::ReleaseLock()
147//              Purpose: Release the lock. Exceptions if the lock is not held
148//              Created: 2003/08/28
149//
150// --------------------------------------------------------------------------
151void NamedLock::ReleaseLock()
152{
153        // Got a lock?
154        if(mFileDescriptor == -1)
155        {
156                THROW_EXCEPTION(CommonException, NamedLockNotHeld)
157        }
158       
159        // Close the file
160        if(::close(mFileDescriptor) != 0)
161        {
162                THROW_EXCEPTION(CommonException, OSFileError)
163        }
164        // Mark as unlocked
165        mFileDescriptor = -1;
166}
167
168
169
170
Note: See TracBrowser for help on using the repository browser.