1 /*
2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. 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, version 2.0,
6  * as published by the Free Software Foundation.
7  *
8  * This program is also distributed with certain software (including
9  * but not limited to OpenSSL) that is licensed under separate terms,
10  * as designated in a particular file or component or in included license
11  * documentation.  The authors of MySQL hereby grant you an additional
12  * permission to link the program and your derivative works with the
13  * separately licensed software that they have included with MySQL.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License, version 2.0, for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23  */
24 
25 #ifndef PLUGIN_X_SRC_HELPER_MULTITHREAD_SYNCHRONIZE_H_
26 #define PLUGIN_X_SRC_HELPER_MULTITHREAD_SYNCHRONIZE_H_
27 
28 #include "plugin/x/src/helper/multithread/cond.h"
29 #include "plugin/x/src/helper/multithread/mutex.h"
30 
31 namespace xpl {
32 
33 class Synchronize {
34  public:
Synchronize(PSI_mutex_key mutex_key,PSI_cond_key cond_key)35   Synchronize(PSI_mutex_key mutex_key, PSI_cond_key cond_key)
36       : m_mutex(mutex_key), m_cond(cond_key) {}
37 
38   class Block {
39    public:
~Block()40     ~Block() {
41       if (m_release_lock) mysql_mutex_unlock(m_sync->m_mutex);
42     }
43 
Block(Block && block)44     Block(Block &&block)
45         : m_release_lock(block.m_release_lock), m_sync(block.m_sync) {
46       block.m_release_lock = false;
47     }
48 
wait()49     void wait() { m_sync->m_cond.wait(m_sync->m_mutex); }
notify()50     void notify() { m_sync->m_cond.signal(); }
51 
52    private:
53     friend class Synchronize;
54 
55     Block(const Block &) = delete;
Block(Synchronize * sync)56     Block(Synchronize *sync) : m_sync(sync) {
57       m_release_lock = 0 == mysql_mutex_lock(m_sync->m_mutex);
58     }
59 
60     Block &operator=(const Block &) = delete;
61 
62     bool m_release_lock{false};
63     Synchronize *m_sync{nullptr};
64   };
65 
block()66   Block block() { return Block(this); }
67 
68  private:
69   Mutex m_mutex;
70   Cond m_cond;
71 };
72 
73 }  // namespace xpl
74 
75 #endif  // PLUGIN_X_SRC_HELPER_MULTITHREAD_SYNCHRONIZE_H_
76