1 /* Copyright (c) 2003-2005 MySQL AB
2    Use is subject to license terms
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; version 2 of the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #ifndef SHM_Transporter_H
18 #define SHM_Transporter_H
19 
20 #include "Transporter.hpp"
21 #include "SHM_Buffer.hpp"
22 
23 #ifdef NDB_WIN32
24 typedef Uint32 key_t;
25 #endif
26 
27 /**
28  * class SHMTransporter
29  * @brief - main class for the SHM transporter.
30  */
31 
32 class SHM_Transporter : public Transporter {
33   friend class TransporterRegistry;
34 public:
35   SHM_Transporter(TransporterRegistry &,
36 		  const char *lHostName,
37 		  const char *rHostName,
38 		  int r_port,
39 		  bool isMgmConnection,
40 		  NodeId lNodeId,
41 		  NodeId rNodeId,
42 		  NodeId serverNodeId,
43 		  bool checksum,
44 		  bool signalId,
45 		  key_t shmKey,
46 		  Uint32 shmSize);
47 
48   /**
49    * SHM destructor
50    */
51   virtual ~SHM_Transporter();
52 
53   /**
54    * Do initialization
55    */
56   bool initTransporter();
57 
getWritePtr(Uint32 lenBytes,Uint32 prio)58   Uint32 * getWritePtr(Uint32 lenBytes, Uint32 prio)
59   {
60     return (Uint32 *)writer->getWritePtr(lenBytes);
61   }
62 
updateWritePtr(Uint32 lenBytes,Uint32 prio)63   void updateWritePtr(Uint32 lenBytes, Uint32 prio)
64   {
65     writer->updateWritePtr(lenBytes);
66     m_last_signal += lenBytes;
67     if(m_last_signal >= m_signal_threshold)
68     {
69       doSend();
70     }
71   }
72 
getReceivePtr(Uint32 ** ptr,Uint32 ** eod)73   void getReceivePtr(Uint32 ** ptr, Uint32 ** eod){
74     reader->getReadPtr(* ptr, * eod);
75   }
76 
updateReceivePtr(Uint32 * ptr)77   void updateReceivePtr(Uint32 * ptr){
78     reader->updateReadPtr(ptr);
79   }
80 
81 protected:
82   /**
83    * disconnect a segmnet
84    * -# deletes the shm buffer associated with a segment
85    * -# marks the segment for removal
86    */
87   void disconnectImpl();
88 
89   /**
90    * Blocking
91    *
92    * -# Create shm segment
93    * -# Attach to it
94    * -# Wait for someone to attach (max wait = timeout), then rerun again
95    *    until connection established.
96    * @param timeOutMillis - the time to sleep before (ms) trying again.
97    * @returns - True if the server managed to hook up with the client,
98    *            i.e., both agrees that the other one has setup the segment.
99    *            Otherwise false.
100    */
101   virtual bool connect_server_impl(NDB_SOCKET_TYPE sockfd);
102 
103   /**
104    * Blocking
105    *
106    * -# Attach to shm segment
107    * -# Check if the segment is setup
108    * -# Check if the server set it up
109    * -# If all clear, return.
110    * @param timeOutMillis - the time to sleep before (ms) trying again.
111    * @returns - True if the client managed to hook up with the server,
112    *            i.e., both agrees that the other one has setup the segment.
113    *            Otherwise false.
114    */
115   virtual bool connect_client_impl(NDB_SOCKET_TYPE sockfd);
116 
117   bool connect_common(NDB_SOCKET_TYPE sockfd);
118 
119   bool ndb_shm_create();
120   bool ndb_shm_get();
121   bool ndb_shm_attach();
122 
123   /**
124    * Check if there are two processes attached to the segment (a connection)
125    * @return - True if the above holds. Otherwise false.
126    */
127   bool checkConnected();
128 
129 
130   /**
131    * Initialises the SHM_Reader and SHM_Writer on the segment
132    */
133   void setupBuffers();
134 
135   /**
136    * doSend (i.e signal receiver)
137    */
138   void doSend();
139   int m_remote_pid;
140   Uint32 m_last_signal;
141   Uint32 m_signal_threshold;
142 
143   virtual Uint32 get_free_buffer() const;
144 
145 private:
146   bool _shmSegCreated;
147   bool _attached;
148   bool m_connected;
149 
150   key_t shmKey;
151   volatile Uint32 * serverStatusFlag;
152   volatile Uint32 * clientStatusFlag;
153   bool setupBuffersDone;
154 
155 #ifdef NDB_WIN32
156   HANDLE hFileMapping;
157 #else
158   int shmId;
159 #endif
160 
161   int shmSize;
162   char * shmBuf;
163 
164   SHM_Reader * reader;
165   SHM_Writer * writer;
166 
167   /**
168    * @return - True if the reader has data to read on its segment.
169    */
hasDataToRead() const170   bool hasDataToRead() const {
171     return reader->empty() == false;
172   }
173 
174   void make_error_info(char info[], int sz);
175 };
176 
177 #endif
178