transactd 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/BUILD_UNIX-JA +6 -6
- data/README +20 -18
- data/README-JA +19 -17
- data/RELEASE_NOTE +144 -0
- data/RELEASE_NOTE-JA +153 -0
- data/bin/common/tdclc_32_2_3.dll +0 -0
- data/bin/common/tdclc_64_2_3.dll +0 -0
- data/build/common/get_ruby_path.cmake +1 -1
- data/build/swig/ruby/ruby.swg +10 -9
- data/build/swig/ruby/tdclrb_wrap.cpp +1416 -561
- data/build/swig/tdcl.i +30 -3
- data/build/tdclc/tdclc.cbproj +1 -1
- data/build/tdclc/tdclc.rc +4 -4
- data/build/tdclcpp/BUILDNUMBER.txt +1 -0
- data/build/tdclcpp/tdclcpp.rc +4 -4
- data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
- data/build/tdclrb/BUILDNUMBER.txt +1 -0
- data/build/tdclrb/tdclrb.rc +4 -4
- data/source/bzs/db/engine/mysql/database.cpp +85 -41
- data/source/bzs/db/engine/mysql/database.h +35 -5
- data/source/bzs/db/engine/mysql/mysqlInternal.h +189 -37
- data/source/bzs/db/engine/mysql/mysqlThd.cpp +21 -21
- data/source/bzs/db/protocol/tdap/client/activeTable.cpp +11 -0
- data/source/bzs/db/protocol/tdap/client/activeTable.h +1 -1
- data/source/bzs/db/protocol/tdap/client/activeTableImple.h +11 -4
- data/source/bzs/db/protocol/tdap/client/client.h +30 -1
- data/source/bzs/db/protocol/tdap/client/dbDef.cpp +2 -1
- data/source/bzs/db/protocol/tdap/client/dllmain.cpp +35 -5
- data/source/bzs/db/protocol/tdap/client/field.cpp +100 -51
- data/source/bzs/db/protocol/tdap/client/field.h +7 -7
- data/source/bzs/db/protocol/tdap/client/filter.h +20 -6
- data/source/bzs/db/protocol/tdap/client/groupQuery.cpp +337 -58
- data/source/bzs/db/protocol/tdap/client/groupQuery.h +56 -13
- data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +83 -5
- data/source/bzs/db/protocol/tdap/client/nsDatabase.h +4 -1
- data/source/bzs/db/protocol/tdap/client/nsTable.cpp +2 -2
- data/source/bzs/db/protocol/tdap/client/nsTable.h +2 -1
- data/source/bzs/db/protocol/tdap/client/pooledDatabaseManager.h +20 -6
- data/source/bzs/db/protocol/tdap/client/recordset.cpp +7 -0
- data/source/bzs/db/protocol/tdap/client/recordsetImple.h +8 -4
- data/source/bzs/db/protocol/tdap/client/request.h +11 -1
- data/source/bzs/db/protocol/tdap/client/serializer.cpp +40 -2
- data/source/bzs/db/protocol/tdap/client/serializer.h +4 -2
- data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +1 -0
- data/source/bzs/db/protocol/tdap/client/stringConverter.h +4 -4
- data/source/bzs/db/protocol/tdap/client/table.cpp +124 -71
- data/source/bzs/db/protocol/tdap/client/table.h +8 -7
- data/source/bzs/db/protocol/tdap/client/trdormapi.h +33 -1
- data/source/bzs/db/protocol/tdap/fieldComp.h +1 -1
- data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +3 -1
- data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +20 -4
- data/source/bzs/db/protocol/tdap/mysql/request.h +14 -0
- data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +132 -69
- data/source/bzs/db/protocol/tdap/tdapRequest.h +18 -4
- data/source/bzs/db/protocol/tdap/tdapSchema.cpp +32 -22
- data/source/bzs/db/protocol/tdap/tdapSchema.h +69 -4
- data/source/bzs/db/protocol/tdap/tdapcapi.h +13 -5
- data/source/bzs/db/protocol/tdap/uri.h +4 -4
- data/source/bzs/db/transactd/transactd.cpp +6 -5
- data/source/bzs/env/crosscompile.cpp +17 -0
- data/source/bzs/env/crosscompile.h +4 -1
- data/source/bzs/env/mbcswchrLinux.cpp +3 -0
- data/source/bzs/example/deleteRecords.cpp +13 -0
- data/source/bzs/example/deleteRecords_c.cpp +8 -1
- data/source/bzs/example/insertRecords.cpp +14 -0
- data/source/bzs/example/insertRecords_c.cpp +8 -1
- data/source/bzs/example/ormap_c.cpp +8 -1
- data/source/bzs/example/queryData.cpp +92 -2
- data/source/bzs/example/queryData.h +3 -1
- data/source/bzs/example/readRecords.cpp +13 -0
- data/source/bzs/example/readRecords_c.cpp +8 -1
- data/source/bzs/example/updateRecords.cpp +13 -0
- data/source/bzs/example/updateRecords_c.cpp +8 -1
- data/source/bzs/example/update_with_transaction.cpp +13 -0
- data/source/bzs/example/update_with_transaction_c.cpp +8 -1
- data/source/bzs/example/useORMRecord.cpp +9 -3
- data/source/bzs/netsvc/client/iconnection.h +8 -0
- data/source/bzs/netsvc/client/tcpClient.cpp +61 -16
- data/source/bzs/netsvc/client/tcpClient.h +430 -214
- data/source/bzs/netsvc/server/serverPipe.cpp +2 -2
- data/source/bzs/test/tdclphp/transactd_Test.php +115 -19
- data/source/bzs/test/tdclphp/transactd_blob_Test.php +33 -5
- data/source/bzs/test/tdclphp/transactd_kanjischema_Test.php +21 -3
- data/source/bzs/test/tdclphp/transactd_pool_Test.php +17 -3
- data/source/bzs/test/tdclrb/transactd_blob_spec.rb +26 -8
- data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +13 -6
- data/source/bzs/test/tdclrb/transactd_pool_spec.rb +14 -8
- data/source/bzs/test/tdclrb/transactd_spec.rb +117 -27
- data/source/bzs/test/transactdBench/scaling_bench.cpp +5 -5
- data/source/bzs/test/transactdBench/workerBase.h +2 -2
- data/source/bzs/test/trdclengn/test_trdclengn.cpp +898 -51
- data/source/global/tdclatl/Database.cpp +12 -0
- data/source/global/tdclatl/Database.h +4 -0
- data/source/global/tdclatl/FieldDef.cpp +19 -0
- data/source/global/tdclatl/FieldDef.h +4 -0
- data/source/global/tdclatl/FieldDefs.cpp +14 -16
- data/source/global/tdclatl/GroupQuery.cpp +21 -16
- data/source/global/tdclatl/GroupQuery.h +1 -1
- data/source/global/tdclatl/QueryBase.cpp +14 -0
- data/source/global/tdclatl/QueryBase.h +2 -0
- data/source/global/tdclatl/Record.cpp +41 -10
- data/source/global/tdclatl/Record.h +1 -1
- data/source/global/tdclatl/Recordset.cpp +117 -31
- data/source/global/tdclatl/Recordset.h +6 -5
- data/source/global/tdclatl/Table.cpp +24 -28
- data/source/global/tdclatl/Table.h +3 -4
- data/source/global/tdclatl/activeTable.cpp +149 -103
- data/source/global/tdclatl/activeTable.h +1 -1
- data/source/global/tdclatl/tdclatl.idl +38 -18
- data/transactd.gemspec +1 -1
- metadata +8 -4
- data/bin/common/tdclc_32_2_2.dll +0 -0
- data/bin/common/tdclc_64_2_2.dll +0 -0
@@ -20,15 +20,20 @@
|
|
20
20
|
================================================================= */
|
21
21
|
|
22
22
|
#include <bzs/netsvc/client/iconnection.h>
|
23
|
+
|
23
24
|
#include <boost/asio/write.hpp>
|
24
25
|
#include <boost/asio/read.hpp>
|
25
26
|
#include <boost/system/system_error.hpp>
|
27
|
+
#include <boost/bind.hpp>
|
26
28
|
#include <boost/thread/mutex.hpp>
|
29
|
+
#if (BOOST_VERSION > 104900)
|
30
|
+
#include <boost/asio/deadline_timer.hpp>
|
31
|
+
#endif
|
27
32
|
#include <stdio.h>
|
28
33
|
#include <vector>
|
29
34
|
#ifdef LINUX
|
30
35
|
#include <pthread.h>
|
31
|
-
#include <signal.h>
|
36
|
+
#include <signal.h>
|
32
37
|
#endif
|
33
38
|
|
34
39
|
|
@@ -39,9 +44,10 @@ using namespace boost::system;
|
|
39
44
|
#define WRITEBUF_SIZE 66000
|
40
45
|
|
41
46
|
#define PORTNUMBUF_SIZE 10
|
42
|
-
#define CLIENT_ERROR_CANT_CREATEPIPE
|
43
|
-
#define CLIENT_ERROR_SHAREMEM_DENIED
|
47
|
+
#define CLIENT_ERROR_CANT_CREATEPIPE 3106
|
48
|
+
#define CLIENT_ERROR_SHAREMEM_DENIED 3104
|
44
49
|
#define CLIENT_ERROR_CONNECTION_FAILURE 3106
|
50
|
+
#define ERROR_TD_NET_TOO_BIGDATA 3802
|
45
51
|
#define MAX_DATA_SIZE 10485760 // 10MB
|
46
52
|
|
47
53
|
namespace bzs
|
@@ -51,13 +57,52 @@ namespace netsvc
|
|
51
57
|
namespace client
|
52
58
|
{
|
53
59
|
|
60
|
+
#ifndef _WIN32
|
61
|
+
|
62
|
+
class signalmask
|
63
|
+
{
|
64
|
+
sigset_t m_signmask, m_sigomask;
|
65
|
+
public:
|
66
|
+
signalmask()
|
67
|
+
{
|
68
|
+
sigfillset(&m_signmask);
|
69
|
+
sigdelset(&m_signmask, SIGQUIT | SIGKILL | SIGHUP | SIGINT |SIGTERM);
|
70
|
+
pthread_sigmask(SIG_SETMASK, &m_signmask , &m_sigomask);
|
71
|
+
}
|
72
|
+
|
73
|
+
~signalmask()
|
74
|
+
{
|
75
|
+
pthread_sigmask(SIG_SETMASK, &m_sigomask, NULL);
|
76
|
+
}
|
77
|
+
};
|
78
|
+
#endif
|
79
|
+
|
80
|
+
class exception : public std::exception
|
81
|
+
{
|
82
|
+
int m_error;
|
83
|
+
std::string m_msg;
|
84
|
+
|
85
|
+
public:
|
86
|
+
exception(int errorCode, const char* const& message)
|
87
|
+
: std::exception(), m_error(errorCode), m_msg(message)
|
88
|
+
{
|
89
|
+
}
|
90
|
+
|
91
|
+
~exception() throw() {}
|
92
|
+
|
93
|
+
const char* what() const throw() { return m_msg.c_str(); }
|
94
|
+
|
95
|
+
int error() { return m_error; }
|
96
|
+
};
|
97
|
+
|
54
98
|
typedef bool (*handshake)(connection* c, void* data);
|
55
99
|
class connections
|
56
100
|
{
|
57
101
|
std::vector<connection*> m_conns;
|
102
|
+
std::string m_pipeName;
|
58
103
|
boost::asio::io_service m_ios;
|
104
|
+
boost::asio::ip::tcp::resolver m_resolver;
|
59
105
|
mutex m_mutex;
|
60
|
-
std::string m_pipeName;
|
61
106
|
static bool m_usePipedLocal;
|
62
107
|
|
63
108
|
connection* getConnection(asio::ip::tcp::endpoint& ep);
|
@@ -75,11 +120,15 @@ public:
|
|
75
120
|
~connections();
|
76
121
|
connection* connect(const std::string& host, handshake f,
|
77
122
|
void* data, bool newConnection = false);
|
123
|
+
bool reconnect(connection* c, const std::string& host,
|
124
|
+
handshake f, void* data);
|
125
|
+
|
78
126
|
connection* getConnection(const std::string& host);
|
79
127
|
bool disconnect(connection* c);
|
80
128
|
int connectionCount();
|
81
129
|
static char port[PORTNUMBUF_SIZE];
|
82
|
-
static
|
130
|
+
static int connectTimeout;
|
131
|
+
static int netTimeout;
|
83
132
|
};
|
84
133
|
|
85
134
|
/** Implementation of Part of the connection interface
|
@@ -91,8 +140,6 @@ protected:
|
|
91
140
|
|
92
141
|
asio::io_service m_ios;
|
93
142
|
asio::ip::tcp::endpoint m_ep;
|
94
|
-
std::vector<char> m_readbuf;
|
95
|
-
std::vector<char> m_sendbuf;
|
96
143
|
idirectReadHandler* m_reader;
|
97
144
|
size_t m_readLen;
|
98
145
|
int m_refCount;
|
@@ -113,78 +160,267 @@ protected:
|
|
113
160
|
int charsetServer() const { return m_charsetServer; };
|
114
161
|
|
115
162
|
void setCharsetServer(int v) { m_charsetServer = v; }
|
116
|
-
|
163
|
+
|
117
164
|
public:
|
118
165
|
connectionBase(asio::ip::tcp::endpoint& ep)
|
119
166
|
: m_ep(ep), m_reader(NULL), m_refCount(0),
|
120
167
|
m_charsetServer(-1), m_connected(false), m_isHandShakable(true)
|
121
168
|
{
|
122
169
|
}
|
123
|
-
|
124
170
|
void setDirectReadHandler(idirectReadHandler* p){ m_reader = p; }
|
171
|
+
bool isHandShakable() const {return m_isHandShakable;};
|
172
|
+
};
|
125
173
|
|
126
|
-
|
174
|
+
|
175
|
+
template <class T>
|
176
|
+
class asio_tcp_io
|
177
|
+
{
|
178
|
+
T& m_socket;
|
179
|
+
public:
|
180
|
+
asio_tcp_io(T& socket):m_socket(socket){}
|
181
|
+
|
182
|
+
size_t readAll(char* buf, size_t size)
|
127
183
|
{
|
128
|
-
|
129
|
-
|
130
|
-
return &m_sendbuf[0];
|
184
|
+
return asio::read(m_socket, asio::buffer(buf, size),
|
185
|
+
asio::transfer_all());
|
131
186
|
}
|
132
187
|
|
133
|
-
|
188
|
+
size_t readSome(char* buf, size_t size, size_t minimum)
|
189
|
+
{
|
190
|
+
return asio::read(m_socket, asio::buffer(buf, size),
|
191
|
+
asio::transfer_at_least(minimum));
|
192
|
+
}
|
134
193
|
|
135
|
-
void
|
194
|
+
void write(const char* buf, size_t size, int /*flag*/)
|
136
195
|
{
|
137
|
-
|
138
|
-
|
196
|
+
asio::write(m_socket, asio::buffer(buf, size),
|
197
|
+
asio::transfer_all());
|
139
198
|
}
|
140
199
|
|
141
|
-
|
142
|
-
|
200
|
+
template <typename MutableBufferSequence>
|
201
|
+
void writeMultibuffer(const MutableBufferSequence& buffer)
|
202
|
+
{
|
203
|
+
asio::write(m_socket, buffer, asio::transfer_all());
|
204
|
+
}
|
143
205
|
|
144
|
-
|
145
|
-
|
206
|
+
void on_connected() {}
|
207
|
+
|
208
|
+
};
|
209
|
+
|
210
|
+
#if (defined(_WIN32))
|
211
|
+
#define MSG_WAITALL 0x8
|
212
|
+
#define MSG_EOR 0
|
213
|
+
#define MSG_MORE 0
|
214
|
+
#endif
|
215
|
+
|
216
|
+
#ifdef LINUX
|
217
|
+
#define SOCKET_ERROR -1
|
218
|
+
#endif
|
219
|
+
|
220
|
+
#if (BOOST_VERSION > 104900)
|
221
|
+
#define SYSTEM_CATEGORY system_category()
|
222
|
+
#else
|
223
|
+
#define SYSTEM_CATEGORY system_category
|
224
|
+
#endif
|
225
|
+
|
226
|
+
#ifndef __APPLE__
|
227
|
+
template <class T>
|
228
|
+
class native_tcp_io
|
229
|
+
{
|
230
|
+
T& m_socket;
|
231
|
+
int getErrorCode()
|
232
|
+
{
|
233
|
+
#ifndef _WIN32
|
234
|
+
return errno;
|
235
|
+
#else
|
236
|
+
return WSAGetLastError();
|
237
|
+
#endif
|
238
|
+
}
|
239
|
+
|
240
|
+
public:
|
241
|
+
native_tcp_io(T& socket):m_socket(socket){}
|
242
|
+
|
243
|
+
#ifdef _WIN32
|
244
|
+
size_t readAll2(char* buf, size_t size)
|
245
|
+
{
|
246
|
+
int n = 0;
|
247
|
+
do
|
248
|
+
{
|
249
|
+
int nn = recv(m_socket.native(), buf + n, (int)size - n, 0);
|
250
|
+
if (n == SOCKET_ERROR)
|
251
|
+
throw system_error(error_code(getErrorCode(), SYSTEM_CATEGORY));
|
252
|
+
n += nn;
|
253
|
+
}while (n != size);
|
254
|
+
return (size_t)n;
|
255
|
+
}
|
256
|
+
#endif
|
257
|
+
|
258
|
+
size_t readAll(char* buf, size_t size)
|
259
|
+
{
|
260
|
+
errno = 0;
|
261
|
+
int n = recv(m_socket.native(), buf, (int)size, MSG_WAITALL);
|
262
|
+
if (n == SOCKET_ERROR)
|
263
|
+
{
|
264
|
+
#ifdef _WIN32
|
265
|
+
if (WSAEOPNOTSUPP == getErrorCode())
|
266
|
+
return readAll2(buf, size);
|
267
|
+
else
|
268
|
+
#endif
|
269
|
+
throw system_error(error_code(getErrorCode(), SYSTEM_CATEGORY));
|
270
|
+
}
|
271
|
+
return (size_t)n;
|
272
|
+
}
|
273
|
+
|
274
|
+
size_t readSome(char* buf, size_t size, size_t minimum)
|
275
|
+
{
|
276
|
+
errno = 0;
|
277
|
+
int n = recv(m_socket.native(), buf, (int)size, 0);
|
278
|
+
if (n == SOCKET_ERROR)
|
279
|
+
throw system_error(error_code(getErrorCode(), SYSTEM_CATEGORY));
|
280
|
+
return (size_t)n;
|
281
|
+
}
|
282
|
+
|
283
|
+
void write(const char* buf, size_t size, int flag)
|
284
|
+
{
|
285
|
+
errno = 0;
|
286
|
+
int n = send(m_socket.native(), buf, (int)size, flag);
|
287
|
+
if (n == SOCKET_ERROR)
|
288
|
+
throw system_error(error_code(getErrorCode(), SYSTEM_CATEGORY));
|
289
|
+
}
|
290
|
+
|
291
|
+
template <typename MutableBufferSequence>
|
292
|
+
void writeMultibuffer(const MutableBufferSequence& buffer)
|
293
|
+
{
|
294
|
+
buffers::const_iterator it = buffer.begin();
|
295
|
+
buffers::const_iterator ite = buffer.end();
|
296
|
+
while (it != ite)
|
297
|
+
{
|
298
|
+
std::size_t s = asio::buffer_size(*it);
|
299
|
+
const char* p = asio::buffer_cast<const char*>(*it);
|
300
|
+
write(p, s, (it == (ite - 1)) ? MSG_EOR : MSG_MORE);
|
301
|
+
++it;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
|
305
|
+
void on_connected()
|
306
|
+
{
|
307
|
+
#ifndef _WIN32
|
308
|
+
int val = 0;
|
309
|
+
ioctl(m_socket.native(), FIONBIO, &val);
|
310
|
+
#else
|
311
|
+
u_long val = 0;
|
312
|
+
ioctlsocket(m_socket.native(), FIONBIO, &val);
|
313
|
+
#endif
|
314
|
+
}
|
315
|
+
};
|
316
|
+
#endif
|
317
|
+
|
146
318
|
template <class T> class connectionImple : public connectionBase
|
147
319
|
{
|
148
|
-
#ifdef LINUX
|
149
|
-
sigset_t m_signmask, m_sigomask;
|
150
|
-
#endif
|
151
320
|
protected:
|
152
|
-
//unsigned int m_datalen;
|
153
|
-
//unsigned short m_rows;
|
154
321
|
T m_socket;
|
155
322
|
buffers m_optionalBuffes;
|
156
323
|
|
157
|
-
|
158
|
-
|
159
|
-
|
324
|
+
void checkError(const system::error_code& e)
|
325
|
+
{
|
326
|
+
if (e)
|
327
|
+
{
|
328
|
+
if (e == asio::error::operation_aborted)
|
329
|
+
throw system_error(asio::error::timed_out);
|
330
|
+
throw system_error(e);
|
331
|
+
}
|
332
|
+
}
|
160
333
|
|
161
|
-
|
162
|
-
// last 4byte is 0xFFFFFFFF, that is specify end of data
|
163
|
-
/*void segmentRead()
|
334
|
+
void cleanup()
|
164
335
|
{
|
165
|
-
|
166
|
-
unsigned short n;
|
167
|
-
while (!end)
|
336
|
+
if (m_connected)
|
168
337
|
{
|
169
|
-
|
170
|
-
|
338
|
+
try
|
339
|
+
{
|
340
|
+
m_ios.stop();
|
341
|
+
m_socket.close();
|
342
|
+
m_ios.reset();
|
343
|
+
}
|
344
|
+
catch (...)
|
345
|
+
{
|
346
|
+
}
|
347
|
+
m_connected = false;
|
348
|
+
}
|
349
|
+
}
|
171
350
|
|
172
|
-
|
173
|
-
|
351
|
+
~connectionImple()
|
352
|
+
{
|
353
|
+
cleanup();
|
354
|
+
}
|
174
355
|
|
175
|
-
|
176
|
-
|
177
|
-
|
356
|
+
char* asyncWriteRead(unsigned int writeSize)
|
357
|
+
{
|
358
|
+
#ifndef _WIN32
|
359
|
+
signalmask smask;
|
360
|
+
#endif
|
361
|
+
write(writeSize);
|
362
|
+
return read();
|
363
|
+
}
|
364
|
+
|
365
|
+
buffers* optionalBuffers() { return &m_optionalBuffes; }
|
366
|
+
|
367
|
+
void reconnect(asio::ip::tcp::endpoint& ep)
|
368
|
+
{
|
369
|
+
cleanup();
|
370
|
+
m_ios.reset();
|
371
|
+
m_ep = ep;
|
372
|
+
connect();
|
373
|
+
}
|
374
|
+
|
375
|
+
public:
|
376
|
+
connectionImple(asio::ip::tcp::endpoint& ep)
|
377
|
+
: connectionBase(ep)/*, m_datalen(0)*/, m_socket(m_ios)
|
378
|
+
{
|
379
|
+
}
|
380
|
+
};
|
381
|
+
|
382
|
+
#define _size_holder asio::placeholders::bytes_transferred
|
383
|
+
#define _error_holder asio::placeholders::error
|
384
|
+
|
385
|
+
/** Implementation of The TCP connection.
|
386
|
+
*/
|
387
|
+
#if (defined(LINUX) && (BOOST_VERSION > 104900))
|
388
|
+
#define USE_CONNECT_TIMER
|
389
|
+
#endif
|
390
|
+
|
391
|
+
template <class T>
|
392
|
+
class tcpConnection : public connectionImple<asio::ip::tcp::socket>
|
393
|
+
{
|
394
|
+
T s_io;
|
395
|
+
#ifdef USE_CONNECT_TIMER
|
396
|
+
asio::deadline_timer m_timer;
|
397
|
+
#endif
|
398
|
+
std::vector<char> m_readbuf;
|
399
|
+
std::vector<char> m_sendbuf;
|
400
|
+
|
401
|
+
void resizeReadBuffer(unsigned int n)
|
402
|
+
{
|
403
|
+
if (n > MAX_DATA_SIZE)
|
404
|
+
throw exception(ERROR_TD_NET_TOO_BIGDATA, "read");
|
405
|
+
if (n > m_readbuf.size())
|
406
|
+
m_readbuf.resize(n);
|
407
|
+
}
|
408
|
+
|
409
|
+
char* sendBuffer(size_t size)
|
410
|
+
{
|
411
|
+
if (size > m_sendbuf.size())
|
412
|
+
m_sendbuf.resize(size);
|
413
|
+
return &m_sendbuf[0];
|
414
|
+
}
|
415
|
+
|
416
|
+
unsigned int sendBufferSize() { return (unsigned int)m_sendbuf.size(); };
|
417
|
+
|
418
|
+
void setReadBufferSizeIf(size_t size)
|
419
|
+
{
|
420
|
+
if (m_readbuf.size() < size)
|
421
|
+
m_readbuf.resize(size);
|
422
|
+
}
|
178
423
|
|
179
|
-
end = (*((unsigned int*)(&m_readbuf[m_readLen - 4])) == 0xFFFFFFFF);
|
180
|
-
}
|
181
|
-
m_readLen -= 4;
|
182
|
-
// additinal data length info
|
183
|
-
boost::asio::read(m_socket, boost::asio::buffer(&m_datalen, 4),
|
184
|
-
boost::asio::transfer_all());
|
185
|
-
boost::asio::read(m_socket, boost::asio::buffer(&m_rows, 2),
|
186
|
-
boost::asio::transfer_all());
|
187
|
-
}*/
|
188
424
|
bool queryFunction(unsigned int v)
|
189
425
|
{
|
190
426
|
if (v == CONNECTION_FUNCTION_DIRECT_READ)
|
@@ -192,78 +428,112 @@ protected:
|
|
192
428
|
return false;
|
193
429
|
}
|
194
430
|
|
431
|
+
void cleanup()
|
432
|
+
{
|
433
|
+
#ifdef USE_CONNECT_TIMER
|
434
|
+
m_timer.cancel();
|
435
|
+
#endif
|
436
|
+
connectionImple<asio::ip::tcp::socket>::cleanup();
|
437
|
+
}
|
438
|
+
#ifdef USE_CONNECT_TIMER
|
439
|
+
void setTimer(int time)
|
440
|
+
{
|
441
|
+
#ifdef _WIN32
|
442
|
+
time /= 1000;
|
443
|
+
#endif
|
444
|
+
m_timer.cancel();
|
445
|
+
m_timer.expires_from_now(boost::posix_time::seconds(time));
|
446
|
+
m_timer.async_wait(boost::bind(&tcpConnection::on_timer, this, _1));
|
447
|
+
}
|
448
|
+
#endif
|
449
|
+
|
450
|
+
void on_connect(const boost::system::error_code& e)
|
451
|
+
{
|
452
|
+
#ifdef USE_CONNECT_TIMER
|
453
|
+
m_timer.cancel();
|
454
|
+
#endif
|
455
|
+
checkError(e);
|
456
|
+
s_io.on_connected();
|
457
|
+
m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
|
458
|
+
m_connected = true;
|
459
|
+
setTimeouts(connections::netTimeout);
|
460
|
+
}
|
461
|
+
|
462
|
+
void on_timer(const boost::system::error_code& e)
|
463
|
+
{
|
464
|
+
if (e) return;
|
465
|
+
#pragma warning(disable : 4996)
|
466
|
+
try{ m_socket.cancel(); } catch (...) {}
|
467
|
+
#pragma warning(default : 4996)
|
468
|
+
}
|
469
|
+
|
470
|
+
void setTimeouts(int time)
|
471
|
+
{
|
472
|
+
struct timeval timeout;
|
473
|
+
timeout.tv_usec = 0;
|
474
|
+
timeout.tv_sec = time;
|
475
|
+
int ret = setsockopt(m_socket.native(), SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout,
|
476
|
+
sizeof(timeout));
|
477
|
+
ret = setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout,
|
478
|
+
sizeof(timeout));
|
479
|
+
}
|
480
|
+
#ifdef USE_CONNECT_TIMER
|
481
|
+
void connect()
|
482
|
+
{
|
483
|
+
m_socket.async_connect(m_ep,
|
484
|
+
bind(&tcpConnection::on_connect, this, _error_holder));
|
485
|
+
setTimer(connections::connectTimeout);
|
486
|
+
m_ios.run();
|
487
|
+
m_ios.reset();
|
488
|
+
}
|
489
|
+
|
490
|
+
void connect()
|
491
|
+
{
|
492
|
+
setTimeouts(connections::connectTimeout);
|
493
|
+
m_socket.connect(m_ep);
|
494
|
+
boost::system::error_code e;
|
495
|
+
on_connect(e);
|
496
|
+
m_ios.reset();
|
497
|
+
}
|
498
|
+
#endif
|
499
|
+
|
195
500
|
unsigned int directRead(void* buf, unsigned int size)
|
196
501
|
{
|
197
|
-
return (unsigned int)
|
198
|
-
boost::asio::buffer(buf, size),
|
199
|
-
boost::asio::transfer_all());
|
502
|
+
return (unsigned int)s_io.readAll((char*)buf, size);
|
200
503
|
}
|
201
504
|
|
202
505
|
void* directReadRemain(unsigned int size)
|
203
506
|
{
|
204
507
|
if (size > m_readbuf.size())
|
205
508
|
m_readbuf.resize(size);
|
206
|
-
|
207
|
-
m_readLen += boost::asio::read(
|
208
|
-
m_socket,
|
209
|
-
boost::asio::buffer(&m_readbuf[0], size),
|
210
|
-
boost::asio::transfer_all());
|
509
|
+
m_readLen += s_io.readAll(&m_readbuf[0], size);
|
211
510
|
return &m_readbuf[0];
|
212
|
-
}
|
213
|
-
|
214
|
-
template <typename CompletionCondition, typename MutableBufferSequence>
|
215
|
-
size_t doRead(const MutableBufferSequence& buf, CompletionCondition cnd)
|
216
|
-
{
|
217
|
-
boost::system::error_code e;
|
218
|
-
#ifdef LINUX
|
219
|
-
pthread_sigmask(SIG_SETMASK, &m_signmask , &m_sigomask);
|
220
|
-
#endif
|
221
|
-
size_t n = boost::asio::read(m_socket, buf, cnd, e);
|
222
|
-
#ifdef LINUX
|
223
|
-
pthread_sigmask(SIG_SETMASK, &m_sigomask, NULL);
|
224
|
-
#endif
|
225
|
-
if (e) throw e;
|
226
|
-
return n;
|
227
|
-
}
|
228
|
-
|
511
|
+
}
|
512
|
+
|
229
513
|
char* read()
|
230
514
|
{
|
231
515
|
if (!m_connected)
|
232
516
|
throw system_error(asio::error::not_connected);
|
233
517
|
m_readLen = 0;
|
234
|
-
|
235
|
-
//m_rows = 0;
|
236
|
-
unsigned int n;
|
237
|
-
|
238
|
-
//m_readLen += boost::asio::read(m_socket, boost::asio::buffer(&n, 4),
|
239
|
-
// boost::asio::transfer_all());
|
240
|
-
/*if (n == 0xFFFFFFFF)
|
241
|
-
{
|
242
|
-
segmentRead();
|
243
|
-
m_readLen += boost::asio::read(m_socket, boost::asio::buffer(&n, 4),
|
244
|
-
boost::asio::transfer_all());
|
245
|
-
}*/
|
518
|
+
unsigned int n;
|
246
519
|
if (m_reader)
|
247
520
|
{
|
248
|
-
m_readLen =
|
249
|
-
|
521
|
+
m_readLen = s_io.readAll((char*)&n, 4);
|
250
522
|
m_readLen += m_reader->onRead(n - 4, this);
|
251
523
|
}else
|
252
524
|
{
|
253
|
-
m_readLen =
|
254
|
-
boost::asio::transfer_at_least(4));
|
525
|
+
m_readLen = s_io.readSome(&m_readbuf[0], m_readbuf.size(), 4);
|
255
526
|
n = *((unsigned int*)(&m_readbuf[0]));
|
256
527
|
}
|
257
|
-
|
528
|
+
|
529
|
+
if (n > m_readLen)
|
258
530
|
{
|
259
|
-
|
260
|
-
|
261
|
-
m_readLen += doRead(boost::asio::buffer(&m_readbuf[m_readLen], n - m_readLen),
|
262
|
-
boost::asio::transfer_all());
|
531
|
+
resizeReadBuffer(n);
|
532
|
+
m_readLen += s_io.readAll(&m_readbuf[m_readLen], n - m_readLen);
|
263
533
|
}
|
264
534
|
return &m_readbuf[0];
|
265
|
-
}
|
266
|
-
|
535
|
+
}
|
536
|
+
|
267
537
|
void write(unsigned int writeSize)
|
268
538
|
{
|
269
539
|
if (!m_connected)
|
@@ -272,105 +542,28 @@ protected:
|
|
272
542
|
{
|
273
543
|
m_optionalBuffes.insert(m_optionalBuffes.begin(),
|
274
544
|
asio::buffer(sendBuffer(0), writeSize));
|
275
|
-
|
276
|
-
boost::asio::transfer_all());
|
545
|
+
s_io.writeMultibuffer(m_optionalBuffes);
|
277
546
|
m_optionalBuffes.clear();
|
278
547
|
}
|
279
548
|
else
|
280
|
-
|
281
|
-
|
282
|
-
}
|
283
|
-
|
284
|
-
public:
|
285
|
-
connectionImple(asio::ip::tcp::endpoint& ep)
|
286
|
-
: connectionBase(ep)/*, m_datalen(0)*/, m_socket(m_ios)
|
287
|
-
{
|
288
|
-
#ifdef LINUX
|
289
|
-
sigfillset(&m_signmask);
|
290
|
-
#endif
|
291
|
-
}
|
292
|
-
|
293
|
-
~connectionImple()
|
294
|
-
{
|
295
|
-
try
|
296
|
-
{
|
297
|
-
m_ios.stop();
|
298
|
-
m_socket.close();
|
299
|
-
}
|
300
|
-
catch (...)
|
301
|
-
{
|
302
|
-
}
|
303
|
-
}
|
304
|
-
|
305
|
-
char* asyncWriteRead(unsigned int writeSize)
|
306
|
-
{
|
307
|
-
write(writeSize);
|
308
|
-
return read();
|
309
|
-
}
|
310
|
-
|
311
|
-
buffers* optionalBuffers() { return &m_optionalBuffes; }
|
312
|
-
};
|
313
|
-
|
314
|
-
|
315
|
-
/** Implementation of The TCP connection.
|
316
|
-
*/
|
317
|
-
class tcpConnection : public connectionImple<asio::ip::tcp::socket>
|
318
|
-
{
|
319
|
-
|
549
|
+
s_io.write(sendBuffer(0), writeSize, MSG_EOR);
|
550
|
+
}
|
320
551
|
public:
|
321
552
|
tcpConnection(asio::ip::tcp::endpoint& ep)
|
322
|
-
: connectionImple<asio::ip::tcp::socket>(ep)
|
553
|
+
: connectionImple<asio::ip::tcp::socket>(ep),s_io(m_socket)
|
554
|
+
#ifdef USE_CONNECT_TIMER
|
555
|
+
, m_timer(m_ios)
|
556
|
+
#endif
|
323
557
|
{
|
324
558
|
m_readbuf.resize(READBUF_SIZE);
|
325
559
|
m_sendbuf.resize(WRITEBUF_SIZE);
|
326
|
-
}
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
#
|
331
|
-
|
332
|
-
|
333
|
-
(const char*)&timeout, sizeof(timeout));
|
334
|
-
setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO,
|
335
|
-
(const char*)&timeout, sizeof(timeout));
|
336
|
-
#else
|
337
|
-
struct timeval timeout;
|
338
|
-
timeout.tv_usec = 0;
|
339
|
-
timeout.tv_sec = connections::timeout;
|
340
|
-
setsockopt(m_socket.native(), SOL_SOCKET, SO_RCVTIMEO, &timeout,
|
341
|
-
sizeof(timeout));
|
342
|
-
setsockopt(m_socket.native(), SOL_SOCKET, SO_SNDTIMEO, &timeout,
|
343
|
-
sizeof(timeout));
|
344
|
-
#endif
|
345
|
-
}
|
346
|
-
|
347
|
-
void connect()
|
348
|
-
{
|
349
|
-
setupTimeouts();
|
350
|
-
m_socket.connect(m_ep);
|
351
|
-
m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
|
352
|
-
m_connected = true;
|
353
|
-
}
|
354
|
-
};
|
355
|
-
|
356
|
-
class exception : public std::exception
|
357
|
-
{
|
358
|
-
int m_error;
|
359
|
-
|
360
|
-
std::string m_msg;
|
361
|
-
|
362
|
-
public:
|
363
|
-
exception(int errorCode, const char* const& message)
|
364
|
-
: std::exception(), m_error(errorCode), m_msg(message)
|
365
|
-
{
|
366
|
-
}
|
367
|
-
|
368
|
-
~exception() throw() {}
|
369
|
-
|
370
|
-
const char* what() const throw() { return m_msg.c_str(); }
|
371
|
-
|
372
|
-
int error() { return m_error; }
|
373
|
-
};
|
560
|
+
}
|
561
|
+
};
|
562
|
+
#ifdef __APPLE__
|
563
|
+
typedef tcpConnection<asio_tcp_io<asio::ip::tcp::socket> > asio_tcpConnection;
|
564
|
+
#else
|
565
|
+
typedef tcpConnection<native_tcp_io<asio::ip::tcp::socket> > native_tcpConnection;
|
566
|
+
#endif
|
374
567
|
|
375
568
|
#ifdef USE_PIPE_CLIENT
|
376
569
|
|
@@ -388,6 +581,18 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
388
581
|
HANDLE m_sendEvent;
|
389
582
|
HANDLE m_mapFile;
|
390
583
|
|
584
|
+
unsigned int directRead(void* buf, unsigned int size)
|
585
|
+
{
|
586
|
+
assert(0);
|
587
|
+
return 0;
|
588
|
+
}
|
589
|
+
|
590
|
+
void* directReadRemain(unsigned int size)
|
591
|
+
{
|
592
|
+
assert(0);
|
593
|
+
return NULL;
|
594
|
+
}
|
595
|
+
|
391
596
|
bool queryFunction(unsigned int v)
|
392
597
|
{
|
393
598
|
if (v == CONNECTION_FUNCTION_DIRECT_READ)
|
@@ -418,10 +623,9 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
418
623
|
throw exception(errorCode, buf);
|
419
624
|
}
|
420
625
|
|
421
|
-
char* getUniqName(const char* name)
|
626
|
+
char* getUniqName(const char* name, char* buf)
|
422
627
|
{
|
423
|
-
|
424
|
-
char* p = &connectionBase::m_readbuf[0];
|
628
|
+
char* p = buf;
|
425
629
|
DWORD processId = GetCurrentProcessId();
|
426
630
|
__int64 clientid = (__int64) this;
|
427
631
|
sprintf_s(p, 120, "%s_%u_%Lu", name, processId, clientid);
|
@@ -431,6 +635,7 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
431
635
|
void createKernelObjects(unsigned int shareMemSize)
|
432
636
|
{
|
433
637
|
char tmp[50];
|
638
|
+
char buf[120];
|
434
639
|
SYSTEM_INFO SystemInfo;
|
435
640
|
GetSystemInfo(&SystemInfo);
|
436
641
|
int size = shareMemSize / SystemInfo.dwAllocationGranularity + 1;
|
@@ -439,7 +644,7 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
439
644
|
sprintf_s(tmp, 50, "Global\\%s", m_pipeName.c_str());
|
440
645
|
m_mapFile =
|
441
646
|
CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
|
442
|
-
m_sendBufferSize * 2, getUniqName(tmp));
|
647
|
+
m_sendBufferSize * 2, getUniqName(tmp, buf));
|
443
648
|
if (m_mapFile == NULL)
|
444
649
|
throwException("CreateFileMapping", CLIENT_ERROR_SHAREMEM_DENIED);
|
445
650
|
|
@@ -454,12 +659,12 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
454
659
|
throwException("MapViewOfFile W", CLIENT_ERROR_SHAREMEM_DENIED);
|
455
660
|
|
456
661
|
sprintf_s(tmp, 50, "Global\\%sToClnt", m_pipeName.c_str());
|
457
|
-
m_recvEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp));
|
662
|
+
m_recvEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp, buf));
|
458
663
|
if (m_recvEvent == NULL)
|
459
664
|
throwException("OpenEvent Client", CLIENT_ERROR_SHAREMEM_DENIED);
|
460
665
|
|
461
666
|
sprintf_s(tmp, 50, "Global\\%sToSrv", m_pipeName.c_str());
|
462
|
-
m_sendEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp));
|
667
|
+
m_sendEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, getUniqName(tmp, buf));
|
463
668
|
if (m_sendEvent == NULL)
|
464
669
|
throwException("OpenEvent Server", CLIENT_ERROR_SHAREMEM_DENIED);
|
465
670
|
}
|
@@ -475,7 +680,7 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
475
680
|
|
476
681
|
char* read()
|
477
682
|
{
|
478
|
-
while (WAIT_TIMEOUT == WaitForSingleObject(m_recvEvent, connections::
|
683
|
+
while (WAIT_TIMEOUT == WaitForSingleObject(m_recvEvent, connections::netTimeout))
|
479
684
|
{
|
480
685
|
DWORD n = 0;
|
481
686
|
BOOL ret = GetNamedPipeHandleState(m_socket.native(), NULL, &n,
|
@@ -486,33 +691,29 @@ class pipeConnection : public connectionImple<platform_stream>
|
|
486
691
|
return m_readbuf_p;
|
487
692
|
}
|
488
693
|
|
489
|
-
|
490
|
-
pipeConnection(asio::ip::tcp::endpoint& ep, const std::string& pipeName)
|
491
|
-
: connectionImple<platform_stream>(ep), m_pipeName(pipeName),
|
492
|
-
m_mapFile(NULL), m_recvEvent(NULL), m_sendEvent(NULL),
|
493
|
-
m_writebuf_p(NULL), m_readbuf_p(NULL), m_sendBufferSize(0)
|
494
|
-
|
694
|
+
~pipeConnection()
|
495
695
|
{
|
696
|
+
cleanup();
|
496
697
|
}
|
497
698
|
|
498
|
-
|
699
|
+
void cleanup()
|
499
700
|
{
|
500
701
|
if (m_connected)
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
702
|
+
{
|
703
|
+
if (m_writebuf_p)
|
704
|
+
memset(m_writebuf_p, 0, sizeof(unsigned int));
|
705
|
+
DWORD n = 0;
|
706
|
+
BOOL ret = GetNamedPipeHandleState(m_socket.native(), NULL, &n,
|
506
707
|
NULL, NULL, NULL, 0);
|
507
708
|
if(m_sendEvent && ret && n)
|
508
709
|
{
|
509
|
-
|
710
|
+
SetEvent(m_sendEvent);
|
510
711
|
//Wait for server side close connection
|
511
712
|
while (WAIT_TIMEOUT ==
|
512
|
-
WaitForSingleObject(m_recvEvent, connections::
|
713
|
+
WaitForSingleObject(m_recvEvent, connections::connectTimeout))
|
513
714
|
;
|
514
715
|
}
|
515
|
-
|
716
|
+
}
|
516
717
|
if (m_recvEvent)
|
517
718
|
CloseHandle(m_recvEvent);
|
518
719
|
if (m_sendEvent)
|
@@ -523,6 +724,12 @@ public:
|
|
523
724
|
UnmapViewOfFile(m_readbuf_p);
|
524
725
|
if (m_mapFile)
|
525
726
|
CloseHandle(m_mapFile);
|
727
|
+
m_sendEvent = NULL;
|
728
|
+
m_recvEvent = NULL;
|
729
|
+
m_writebuf_p = NULL;
|
730
|
+
m_readbuf_p = NULL;
|
731
|
+
m_mapFile = NULL;
|
732
|
+
connectionImple<platform_stream>::cleanup();
|
526
733
|
}
|
527
734
|
|
528
735
|
void connect()
|
@@ -551,8 +758,8 @@ public:
|
|
551
758
|
// send processId and clientid;
|
552
759
|
DWORD processId = GetCurrentProcessId();
|
553
760
|
int size = 16;
|
554
|
-
|
555
|
-
char* p =
|
761
|
+
char buf[256];
|
762
|
+
char* p = buf;
|
556
763
|
memcpy(p, &size, sizeof(int));
|
557
764
|
memcpy(p + 4, &processId, sizeof(DWORD));
|
558
765
|
__int64 clientid = (__int64) this;
|
@@ -572,6 +779,15 @@ public:
|
|
572
779
|
buffers* optionalBuffers() { return NULL; } // not support
|
573
780
|
|
574
781
|
void setReadBufferSizeIf(size_t size) {} // not support
|
782
|
+
|
783
|
+
public:
|
784
|
+
pipeConnection(asio::ip::tcp::endpoint& ep, const std::string& pipeName)
|
785
|
+
: connectionImple<platform_stream>(ep), m_pipeName(pipeName),
|
786
|
+
m_mapFile(NULL), m_recvEvent(NULL), m_sendEvent(NULL),
|
787
|
+
m_writebuf_p(NULL), m_readbuf_p(NULL), m_sendBufferSize(0)
|
788
|
+
|
789
|
+
{
|
790
|
+
}
|
575
791
|
};
|
576
792
|
#endif // NOT WIN32
|
577
793
|
|