1 /*
2    Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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 SHM_Transporter_H
26 #define SHM_Transporter_H
27 
28 #include "Transporter.hpp"
29 #include "SHM_Buffer.hpp"
30 
31 #ifdef NDB_WIN32
32 typedef Uint32 key_t;
33 #endif
34 
35 /**
36  * class SHMTransporter
37  * @brief - main class for the SHM transporter.
38  */
39 
40 class SHM_Transporter : public Transporter {
41   friend class TransporterRegistry;
42 public:
43   SHM_Transporter(TransporterRegistry &,
44 		  const char *lHostName,
45 		  const char *rHostName,
46 		  int r_port,
47 		  bool isMgmConnection,
48 		  NodeId lNodeId,
49 		  NodeId rNodeId,
50 		  NodeId serverNodeId,
51 		  bool checksum,
52 		  bool signalId,
53 		  key_t shmKey,
54 		  Uint32 shmSize);
55 
56   /**
57    * SHM destructor
58    */
59   virtual ~SHM_Transporter();
60 
61   virtual bool configure_derived(const TransporterConfiguration* conf);
62 
63   /**
64    * Do initialization
65    */
66   bool initTransporter();
67 
getReceivePtr(Uint32 ** ptr,Uint32 ** eod)68   void getReceivePtr(Uint32 ** ptr, Uint32 ** eod){
69     reader->getReadPtr(* ptr, * eod);
70   }
71 
updateReceivePtr(Uint32 * ptr)72   void updateReceivePtr(Uint32 * ptr){
73     reader->updateReadPtr(ptr);
74   }
75 
76 protected:
77   /**
78    * disconnect a segmnet
79    * -# deletes the shm buffer associated with a segment
80    * -# marks the segment for removal
81    */
82   void disconnectImpl();
83 
84   /**
85    * Blocking
86    *
87    * -# Create shm segment
88    * -# Attach to it
89    * -# Wait for someone to attach (max wait = timeout), then rerun again
90    *    until connection established.
91    * @param timeOutMillis - the time to sleep before (ms) trying again.
92    * @returns - True if the server managed to hook up with the client,
93    *            i.e., both agrees that the other one has setup the segment.
94    *            Otherwise false.
95    */
96   virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd);
97 
98   /**
99    * Blocking
100    *
101    * -# Attach to shm segment
102    * -# Check if the segment is setup
103    * -# Check if the server set it up
104    * -# If all clear, return.
105    * @param timeOutMillis - the time to sleep before (ms) trying again.
106    * @returns - True if the client managed to hook up with the server,
107    *            i.e., both agrees that the other one has setup the segment.
108    *            Otherwise false.
109    */
110   virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd);
111 
112   bool connect_common(NDB_SOCKET_TYPE sockfd);
113 
114   bool ndb_shm_create();
115   bool ndb_shm_get();
116   bool ndb_shm_attach();
117 
118   /**
119    * Check if there are two processes attached to the segment (a connection)
120    * @return - True if the above holds. Otherwise false.
121    */
122   bool checkConnected();
123 
124 
125   /**
126    * Initialises the SHM_Reader and SHM_Writer on the segment
127    */
128   void setupBuffers();
129 
130   /**
131    * doSend (i.e signal receiver)
132    */
133   bool doSend();
134   int m_remote_pid;
135   Uint32 m_signal_threshold;
136 
137 private:
138   bool _shmSegCreated;
139   bool _attached;
140   bool m_connected;
141 
142   key_t shmKey;
143   volatile Uint32 * serverStatusFlag;
144   volatile Uint32 * clientStatusFlag;
145   bool setupBuffersDone;
146 
147 #ifdef NDB_WIN32
148   HANDLE hFileMapping;
149 #else
150   int shmId;
151 #endif
152 
153   int shmSize;
154   char * shmBuf;
155 
156   SHM_Reader * reader;
157   SHM_Writer * writer;
158 
159   /**
160    * @return - True if the reader has data to read on its segment.
161    */
hasDataToRead() const162   bool hasDataToRead() const {
163     return reader->empty() == false;
164   }
165 
166   void make_error_info(char info[], int sz);
167 
send_limit_reached(int bufsize)168   bool send_limit_reached(int bufsize)
169   {
170     return ((Uint32)bufsize >= m_signal_threshold);
171   }
send_is_possible(int timeout_millisec) const172   bool send_is_possible(int timeout_millisec) const { return 1; }
173 };
174 
175 #endif
176