Line data Source code
1 : // Snap Lock -- class used to have inter-process locks in a Snap! cluster
2 : // Copyright (c) 2016-2019 Made to Order Software Corp. All Rights Reserved
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 2 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, write to the Free Software
16 : // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 : #pragma once
18 :
19 : #include "snapwebsites/snap_communicator.h"
20 :
21 : namespace snap
22 : {
23 :
24 0 : class snap_lock_exception : public snap_exception
25 : {
26 : public:
27 0 : explicit snap_lock_exception(char const * what_msg) : snap_exception("snap_lock", what_msg) {}
28 : explicit snap_lock_exception(std::string const & what_msg) : snap_exception("snap_lock", what_msg) {}
29 0 : explicit snap_lock_exception(QString const & what_msg) : snap_exception("snap_lock", what_msg) {}
30 : };
31 :
32 0 : class snap_lock_failed_exception : public snap_lock_exception
33 : {
34 : public:
35 : explicit snap_lock_failed_exception(char const * what_msg) : snap_lock_exception(what_msg) {}
36 : explicit snap_lock_failed_exception(std::string const & what_msg) : snap_lock_exception(what_msg) {}
37 0 : explicit snap_lock_failed_exception(QString const & what_msg) : snap_lock_exception(what_msg) {}
38 : };
39 :
40 0 : class snap_lock_not_initialized : public snap_lock_exception
41 : {
42 : public:
43 0 : explicit snap_lock_not_initialized(char const * what_msg) : snap_lock_exception(what_msg) {}
44 : explicit snap_lock_not_initialized(std::string const & what_msg) : snap_lock_exception(what_msg) {}
45 : explicit snap_lock_not_initialized(QString const & what_msg) : snap_lock_exception(what_msg) {}
46 : };
47 :
48 :
49 :
50 :
51 : // the lock internal implementation
52 : namespace details
53 : {
54 : class lock_connection;
55 : }
56 :
57 :
58 : /** \brief Inter-computer snap_lock.
59 : *
60 : * \todo
61 : * We may want to rethink about the name because we already have a snap_lock
62 : * inside our snap_thread.
63 : */
64 0 : class snap_lock
65 : {
66 : public:
67 : typedef std::shared_ptr<snap_lock> pointer_t;
68 : typedef int32_t timeout_t;
69 :
70 : static constexpr timeout_t SNAP_LOCK_DEFAULT_TIMEOUT = 5; // in seconds
71 : static constexpr timeout_t SNAP_LOCK_MINIMUM_TIMEOUT = 3; // in seconds
72 : static constexpr timeout_t SNAP_UNLOCK_MINIMUM_TIMEOUT = 60; // in seconds
73 : static constexpr timeout_t SNAP_UNLOCK_USES_LOCK_TIMEOUT = -1; // use lock_duration as the unlock_duration
74 : static constexpr timeout_t SNAP_MAXIMUM_OBTENTION_TIMEOUT = 60 * 60; // limit obtension timeout to this value
75 : static constexpr timeout_t SNAP_MAXIMUM_TIMEOUT = 7 * 24 * 60 * 60; // no matter what limit all timeouts to this value (7 days)
76 :
77 : snap_lock(
78 : QString const & object_name
79 : , timeout_t lock_duration = -1
80 : , timeout_t lock_obtention_timeout = -1
81 : , timeout_t unlock_duration = SNAP_UNLOCK_USES_LOCK_TIMEOUT);
82 :
83 : static void initialize_lock_duration_timeout(timeout_t timeout);
84 : static timeout_t current_lock_duration_timeout();
85 :
86 : static void initialize_lock_obtention_timeout(timeout_t timeout);
87 : static timeout_t current_lock_obtention_timeout();
88 :
89 : static void initialize_unlock_duration_timeout(timeout_t timeout);
90 : static timeout_t current_unlock_duration_timeout();
91 :
92 : static void initialize_snapcommunicator(
93 : std::string const & addr
94 : , int port
95 : , tcp_client_server::bio_client::mode_t mode = tcp_client_server::bio_client::mode_t::MODE_PLAIN);
96 :
97 : bool lock(
98 : QString const & object_name
99 : , timeout_t lock_duration = -1
100 : , timeout_t lock_obtention_timeout = -1
101 : , timeout_t unlock_duration = SNAP_UNLOCK_USES_LOCK_TIMEOUT);
102 : void unlock();
103 :
104 : time_t get_timeout_date() const;
105 : bool is_locked() const;
106 : bool lock_timedout() const;
107 :
108 : private:
109 : std::shared_ptr<details::lock_connection> f_lock_connection = std::shared_ptr<details::lock_connection>();
110 : };
111 :
112 :
113 : class raii_lock_duration_timeout
114 : {
115 : public:
116 : raii_lock_duration_timeout(snap_lock::timeout_t temporary_lock_timeout);
117 : ~raii_lock_duration_timeout();
118 :
119 : private:
120 : snap_lock::timeout_t f_save_timeout = -1;
121 : };
122 :
123 :
124 : class raii_lock_obtention_timeout
125 : {
126 : public:
127 : raii_lock_obtention_timeout(snap_lock::timeout_t temporary_lock_timeout);
128 : ~raii_lock_obtention_timeout();
129 :
130 : private:
131 : snap_lock::timeout_t f_save_timeout = -1;
132 : };
133 :
134 :
135 : } // namespace snap
136 : // vim: ts=4 sw=4 et
|