transactd 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. checksums.yaml +4 -4
  2. data/bin/common/tdclc_32_2_2.dll +0 -0
  3. data/bin/common/tdclc_64_2_2.dll +0 -0
  4. data/build/swig/ruby/generate.cmd +45 -0
  5. data/build/swig/ruby/generate.sh +40 -0
  6. data/build/swig/ruby/tdclrb_wrap.cpp +406 -969
  7. data/build/swig/tdcl.i +88 -0
  8. data/build/tdclc/CMakeLists.txt +5 -1
  9. data/build/tdclc/tdclc.cbproj +1 -1
  10. data/build/tdclc/tdclc.rc +4 -4
  11. data/build/tdclcpp/tdclcpp.rc +4 -4
  12. data/build/tdclcpp/tdclcpp_bc.cbproj +1 -1
  13. data/build/tdclrb/tdclrb.rc +4 -4
  14. data/source/bzs/db/engine/mysql/database.cpp +165 -74
  15. data/source/bzs/db/engine/mysql/database.h +19 -5
  16. data/source/bzs/db/engine/mysql/dbManager.cpp +33 -11
  17. data/source/bzs/db/engine/mysql/dbManager.h +6 -1
  18. data/source/bzs/db/engine/mysql/mydebuglog.h +12 -0
  19. data/source/bzs/db/engine/mysql/mysqlInternal.h +10 -3
  20. data/source/bzs/db/engine/mysql/mysqlThd.cpp +20 -8
  21. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +12 -7
  22. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +1 -1
  23. data/source/bzs/db/protocol/tdap/client/activeTableImple.h +1 -0
  24. data/source/bzs/db/protocol/tdap/client/client.cpp +17 -15
  25. data/source/bzs/db/protocol/tdap/client/client.h +102 -30
  26. data/source/bzs/db/protocol/tdap/client/connectionPool.cpp +1 -1
  27. data/source/bzs/db/protocol/tdap/client/database.cpp +32 -10
  28. data/source/bzs/db/protocol/tdap/client/database.h +1 -0
  29. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +0 -2
  30. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +2 -0
  31. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +47 -42
  32. data/source/bzs/db/protocol/tdap/client/fields.h +3 -1
  33. data/source/bzs/db/protocol/tdap/client/filter.h +3 -3
  34. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +18 -2
  35. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +3 -2
  36. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +14 -6
  37. data/source/bzs/db/protocol/tdap/client/nsTable.h +12 -12
  38. data/source/bzs/db/protocol/tdap/client/recordsetImple.h +6 -3
  39. data/source/bzs/db/protocol/tdap/client/request.h +1 -0
  40. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +101 -64
  41. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +3 -0
  42. data/source/bzs/db/protocol/tdap/client/stringConverter.h +9 -13
  43. data/source/bzs/db/protocol/tdap/client/table.cpp +73 -56
  44. data/source/bzs/db/protocol/tdap/client/table.h +8 -8
  45. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +52 -100
  46. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +8 -1
  47. data/source/bzs/db/protocol/tdap/mysql/request.h +6 -0
  48. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +349 -189
  49. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +28 -12
  50. data/source/bzs/db/protocol/tdap/tdapRequest.h +5 -4
  51. data/source/bzs/db/protocol/tdap/tdapSchema.h +6 -1
  52. data/source/bzs/db/protocol/tdap/tdapcapi.h +29 -4
  53. data/source/bzs/db/protocol/tdap/uri.h +297 -0
  54. data/source/bzs/db/transactd/appModule.cpp +41 -16
  55. data/source/bzs/db/transactd/appModule.h +1 -2
  56. data/source/bzs/db/transactd/transactd.cpp +37 -14
  57. data/source/bzs/env/crosscompile.h +1 -3
  58. data/source/bzs/example/queryData.cpp +2 -2
  59. data/source/bzs/netsvc/client/iconnection.h +3 -1
  60. data/source/bzs/netsvc/client/tcpClient.cpp +75 -28
  61. data/source/bzs/netsvc/client/tcpClient.h +94 -62
  62. data/source/bzs/netsvc/server/IAppModule.h +2 -2
  63. data/source/bzs/netsvc/server/serverCpt.cpp +17 -10
  64. data/source/bzs/netsvc/server/serverPipe.cpp +26 -19
  65. data/source/bzs/netsvc/server/serverTpool.cpp +8 -2
  66. data/source/bzs/rtl/debuglog.cpp +21 -5
  67. data/source/bzs/rtl/debuglog.h +1 -1
  68. data/source/bzs/test/tdclphp/transactd_Test.php +183 -37
  69. data/source/bzs/test/tdclphp/transactd_pool_Test.php +1 -2
  70. data/source/bzs/test/tdclrb/transactd_spec.rb +183 -39
  71. data/source/bzs/test/transactdBench/scaling_bench.cpp +3 -3
  72. data/source/bzs/test/trdclengn/test_trdclengn.cpp +172 -57
  73. data/source/global/boost/sha1.hpp +223 -0
  74. data/source/global/tdclatl/ConnectParams.cpp +2 -2
  75. data/source/global/tdclatl/ConnectParams.h +1 -1
  76. data/source/global/tdclatl/Database.cpp +18 -0
  77. data/source/global/tdclatl/Database.h +5 -0
  78. data/source/global/tdclatl/tdclatl.idl +23 -1
  79. data/source/linux/linuxTypes.h +2 -0
  80. metadata +8 -6
  81. data/bin/common/tdclc_32_2_1.dll +0 -0
  82. data/bin/common/tdclc_64_2_1.dll +0 -0
  83. data/source/bzs/db/protocol/tdap/client/memRecordset.cpp +0 -448
  84. data/source/bzs/db/protocol/tdap/client/memRecordset.h +0 -159
@@ -54,6 +54,9 @@ unsigned int g_pipeCommSharememSize = 3145728;
54
54
  int g_tableNmaeLower = 1; // defined in btrvProtocol.h
55
55
  unsigned int g_lock_wait_timeout = 1;
56
56
  char* g_transaction_isolation = NULL;
57
+ char* g_auth_type = NULL;
58
+ //int g_grant_apply = 0;//skip
59
+
57
60
 
58
61
  /** tcp server
59
62
  */
@@ -210,6 +213,7 @@ void shutdownSrv(boost::shared_ptr<iserver>& srv)
210
213
  */
211
214
  static int transactd_plugin_deinit(void* p)
212
215
  {
216
+
213
217
  #ifdef PIPE_SERVER
214
218
  shutdownSrv(srv_p);
215
219
  #endif
@@ -245,7 +249,12 @@ static MYSQL_SYSVAR_UINT(lock_wait_timeout, g_lock_wait_timeout,
245
249
  static MYSQL_SYSVAR_STR(transaction_isolation, g_transaction_isolation,
246
250
  PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, NULL, NULL,
247
251
  NULL, "READ-COMMITTED");
248
-
252
+ static MYSQL_SYSVAR_STR(auth_type, g_auth_type,
253
+ PLUGIN_VAR_READONLY | PLUGIN_VAR_MEMALLOC, NULL, NULL,
254
+ NULL, "none"); //or "mysql_native"
255
+ /*static MYSQL_SYSVAR_INT(grant_apply, g_grant_apply,
256
+ PLUGIN_VAR_READONLY, "0..1 0:none 1:all", 0, 0, 0, 0, 1, 0);
257
+ */
249
258
  #ifdef PIPE_SERVER
250
259
  static MYSQL_SYSVAR_UINT(pipe_comm_sharemem_size, g_pipeCommSharememSize,
251
260
  PLUGIN_VAR_READONLY, "66000..52428800", 0, 0, 3145728,
@@ -266,18 +275,26 @@ static MYSQL_SYSVAR_INT(use_handlersocket, g_use_hs, PLUGIN_VAR_READONLY, "", 0,
266
275
 
267
276
  /** system valiables struct.
268
277
  */
269
- static struct st_mysql_sys_var* g_systemVariables[] = {
270
- MYSQL_SYSVAR(address), MYSQL_SYSVAR(port),
271
- MYSQL_SYSVAR(max_tcp_connections), MYSQL_SYSVAR(hostcheck_username),
272
- MYSQL_SYSVAR(table_name_lowercase), MYSQL_SYSVAR(pool_threads),
273
- MYSQL_SYSVAR(tcp_server_type), MYSQL_SYSVAR(lock_wait_timeout),
278
+ static struct st_mysql_sys_var* g_systemVariables[] =
279
+ {
280
+ MYSQL_SYSVAR(address),
281
+ MYSQL_SYSVAR(port),
282
+ MYSQL_SYSVAR(max_tcp_connections),
283
+ MYSQL_SYSVAR(hostcheck_username),
284
+ MYSQL_SYSVAR(table_name_lowercase),
285
+ MYSQL_SYSVAR(pool_threads),
286
+ MYSQL_SYSVAR(tcp_server_type),
287
+ MYSQL_SYSVAR(lock_wait_timeout),
274
288
  MYSQL_SYSVAR(transaction_isolation),
289
+ MYSQL_SYSVAR(auth_type),
275
290
  #ifdef PIPE_SERVER
276
- MYSQL_SYSVAR(pipe_comm_sharemem_size), MYSQL_SYSVAR(max_pipe_connections),
291
+ MYSQL_SYSVAR(pipe_comm_sharemem_size),
292
+ MYSQL_SYSVAR(max_pipe_connections),
277
293
  MYSQL_SYSVAR(use_piped_local),
278
294
  #endif
279
295
  #ifdef USE_HANDLERSOCKET
280
- MYSQL_SYSVAR(use_handlersocket), MYSQL_SYSVAR(hs_port),
296
+ MYSQL_SYSVAR(use_handlersocket),
297
+ MYSQL_SYSVAR(hs_port),
281
298
  #endif
282
299
  0
283
300
  };
@@ -302,12 +319,18 @@ static st_mysql_show_var g_showVariables[] = {
302
319
  */
303
320
  mysql_declare_plugin(transactd)
304
321
  {
305
- MYSQL_DAEMON_PLUGIN, &transactd_info,
306
- "transactd", // this is plugin name for mysql.
307
- "Hisashi Yaguchi at BizStation Corp",
308
- "Transactional access demon for mysql", PLUGIN_LICENSE_GPL,
309
- transactd_plugin_init, transactd_plugin_deinit, 0x0100, g_showVariables,
310
- g_systemVariables, NULL
322
+ MYSQL_DAEMON_PLUGIN,
323
+ &transactd_info,
324
+ "transactd", // this is plugin name for mysql.
325
+ "Hisashi Yaguchi at BizStation Corp",
326
+ "Transactional access demon for mysql",
327
+ PLUGIN_LICENSE_GPL,
328
+ transactd_plugin_init,
329
+ transactd_plugin_deinit,
330
+ 0x0100,
331
+ g_showVariables,
332
+ g_systemVariables,
333
+ NULL
311
334
  }
312
335
 
313
336
  mysql_declare_plugin_end;
@@ -94,8 +94,7 @@ char16_t* wmemcpy(char16_t* dest, const char16_t* src, size_t count);
94
94
  #define PSEPARATOR_C '/'
95
95
  typedef int HWND;
96
96
  #define MAX_PATH 266
97
- #define MCRTOMM 1000 // for usleep(��sec) to Sleep(msec)
98
- #define Sleep usleep
97
+ #define Sleep(A) usleep(A*1000)
99
98
  #define LoadLibrary(A) dlopen(A, RTLD_LAZY)
100
99
  #define LoadLibraryA(A) dlopen(A, RTLD_LAZY)
101
100
  #define GetProcAddress(A, B) dlsym(A, B)
@@ -148,7 +147,6 @@ typedef unsigned __int32 char32_t; // 32bit
148
147
  #define strlen16 wcslen
149
148
 
150
149
  /* operating system */
151
- #define MCRTOMM 1
152
150
  #define PSEPARATOR _T("\\")
153
151
  #define PSEPARATOR_A "\\"
154
152
  #define PSEPARATOR_C '\\'
@@ -376,7 +376,7 @@ int prebuiltData(database_ptr db, const connectParams& param, bool foceCreate,
376
376
  else
377
377
  return 0;
378
378
  }
379
- std::tcout << _T("\nInserting query test data. Please wait ... ")
379
+ std::tcout << _T("\nInserting query test data. Please wait... ")
380
380
  << std::flush;
381
381
  createDatabase(db, param);
382
382
  openDatabase(db, param);
@@ -394,7 +394,7 @@ int prebuiltData(database_ptr db, const connectParams& param, bool foceCreate,
394
394
  }
395
395
  catch (bzs::rtl::exception& e)
396
396
  {
397
- std::tcout << *bzs::rtl::getMsg(e) << std::endl;
397
+ std::tcout << _T("\n") << *bzs::rtl::getMsg(e) << std::endl;
398
398
  return 1;
399
399
  }
400
400
  }
@@ -81,7 +81,6 @@ public:
81
81
  virtual int refCount() const = 0;
82
82
  virtual bool isConnected() const = 0;
83
83
  virtual const boost::asio::ip::tcp::endpoint& endpoint() const = 0;
84
- virtual thread_id tid() const = 0;
85
84
  virtual char* sendBuffer(size_t size) = 0;
86
85
  virtual unsigned int sendBufferSize() = 0;
87
86
  virtual buffers* optionalBuffers() = 0;
@@ -95,6 +94,9 @@ public:
95
94
  virtual bool queryFunction(unsigned int v) = 0;
96
95
  virtual int charsetServer() const = 0;
97
96
  virtual void setCharsetServer(int v) = 0;
97
+ virtual void write(unsigned int writeSize) = 0;
98
+ virtual char* read() = 0;
99
+ virtual bool isHandShakable() const = 0;
98
100
  };
99
101
 
100
102
  #define CONNECTION_FUNCTION_DIRECT_READ 1
@@ -65,7 +65,7 @@ connections::connections(const char* pipeName) : m_pipeName(pipeName)
65
65
  strcpy_s(port, PORTNUMBUF_SIZE, tmp);
66
66
  GetPrivateProfileString("transctd_client", "timeout", "3000", tmp, 30,
67
67
  buf);
68
- timeout = atol(tmp);
68
+ timeout = (short)atol(tmp);
69
69
  }
70
70
  #else // NOT _WIN32
71
71
  #if (BOOST_VERSION > 104900)
@@ -76,7 +76,6 @@ connections::connections(const char* pipeName) : m_pipeName(pipeName)
76
76
  const bool result = fs::exists(path, error);
77
77
  if (result && !error)
78
78
  {
79
-
80
79
  boost::property_tree::ptree pt;
81
80
  try
82
81
  {
@@ -116,10 +115,9 @@ connections::~connections()
116
115
  */
117
116
  connection* connections::getConnection(asio::ip::tcp::endpoint& ep)
118
117
  {
119
- thread_id tid = threadid();
120
118
  for (int i = 0; i < (int)m_conns.size(); i++)
121
119
  {
122
- if ((m_conns[i]->endpoint() == ep) && (m_conns[i]->tid() == tid))
120
+ if (m_conns[i]->endpoint() == ep)
123
121
  return m_conns[i];
124
122
  }
125
123
  return NULL;
@@ -155,13 +153,10 @@ connection* connections::getConnection(const std::string& host)
155
153
 
156
154
  connection* connections::getConnectionPipe()
157
155
  {
158
-
159
- thread_id tid = threadid();
160
156
  for (int i = 0; i < (int)m_conns.size(); i++)
161
157
  {
162
158
  pipeConnection* pc = dynamic_cast<pipeConnection*>(m_conns[i]);
163
- if (pc && (pc->tid() == tid))
164
- return pc;
159
+ return pc;
165
160
  }
166
161
  return NULL;
167
162
  }
@@ -206,37 +201,89 @@ bool connections::isUseNamedPipe(asio::ip::tcp::endpoint& ep)
206
201
  return false;
207
202
  }
208
203
 
204
+ inline connection* connections::createConnection(asio::ip::tcp::endpoint& ep,
205
+ bool namedPipe)
206
+ {
207
+ #ifdef USE_PIPE_CLIENT
208
+ if (namedPipe)
209
+ return new pipeConnection(ep, m_pipeName);
210
+ else
211
+ #endif
212
+ return new tcpConnection(ep);
213
+ }
214
+
215
+ inline connection* connections::doConnect(connection* c)
216
+ {
217
+ try
218
+ {
219
+ c->connect();
220
+ return c;
221
+ }
222
+ catch (bzs::netsvc::client::exception& /*e*/)
223
+ {
224
+ delete c;
225
+ throw;
226
+ }
227
+ catch (boost::system::system_error& /*e*/)
228
+ {
229
+ delete c;
230
+ throw;
231
+ }
232
+ }
233
+
234
+ inline bool connections::doHandShake(connection* c, handshake f, void* data)
235
+ {
236
+ bool ret = true;
237
+ try
238
+ {
239
+ // 1.0 - 2.1 namepd pipe is not HandShakable.
240
+ if (c->isHandShakable())
241
+ {
242
+ if (!f)
243
+ c->read();
244
+ else
245
+ ret = f(c, data);
246
+ if (!ret)
247
+ delete c;
248
+ }
249
+ return ret;
250
+ }
251
+ catch (bzs::netsvc::client::exception& /*e*/)
252
+ {
253
+ delete c;
254
+ throw;
255
+ }
256
+ catch (boost::system::system_error& /*e*/)
257
+ {
258
+ delete c;
259
+ throw;
260
+ }
261
+ }
262
+
209
263
  // The connection of found from connection list of same address is returned.
210
- connection* connections::connect(const std::string& host, bool newConnection)
264
+ connection* connections::connect(const std::string& host, handshake f, void* data, bool newConnection)
211
265
  {
212
- mutex::scoped_lock lck(m_mutex);
213
- connection* c;
266
+ bool namedPipe = false;
214
267
  boost::system::error_code ec;
268
+ connection* c;
269
+ mutex::scoped_lock lck(m_mutex);
215
270
  asio::ip::tcp::endpoint ep = endpoint(host, ec);
216
271
  if (ec)
217
272
  return NULL;
218
273
  #ifdef USE_PIPE_CLIENT
219
- if (m_usePipedLocal && isUseNamedPipe(ep))
220
- {
274
+ namedPipe = (m_usePipedLocal && isUseNamedPipe(ep));
275
+ if (namedPipe)
221
276
  c = newConnection ? NULL : getConnectionPipe();
222
- if (!c)
223
- {
224
- c = new pipeConnection(ep, m_pipeName);
225
- c->connect();
226
- m_conns.push_back(c);
227
- }
228
- }
229
277
  else
230
278
  #endif
231
- {
232
-
233
279
  c = newConnection ? NULL : getConnection(ep);
234
- if (!c)
235
- {
236
- c = new tcpConnection(ep);
237
- c->connect();
238
- m_conns.push_back(c);
239
- }
280
+ if (newConnection || !c)
281
+ {
282
+ c = createConnection(ep, namedPipe);
283
+ c = doConnect(c);
284
+ if (!c || !doHandShake(c, f, data))
285
+ return NULL;
286
+ m_conns.push_back(c);
240
287
  }
241
288
  c->addref();
242
289
  return c;
@@ -26,7 +26,10 @@
26
26
  #include <boost/thread/mutex.hpp>
27
27
  #include <stdio.h>
28
28
  #include <vector>
29
-
29
+ #ifdef LINUX
30
+ #include <pthread.h>
31
+ #include <signal.h>
32
+ #endif
30
33
 
31
34
 
32
35
  using namespace boost;
@@ -39,8 +42,7 @@ using namespace boost::system;
39
42
  #define CLIENT_ERROR_CANT_CREATEPIPE 3106
40
43
  #define CLIENT_ERROR_SHAREMEM_DENIED 3104
41
44
  #define CLIENT_ERROR_CONNECTION_FAILURE 3106
42
- #define TIMEOUT_MILLISEC 3000
43
-
45
+ #define MAX_DATA_SIZE 10485760 // 10MB
44
46
 
45
47
  namespace bzs
46
48
  {
@@ -49,38 +51,35 @@ namespace netsvc
49
51
  namespace client
50
52
  {
51
53
 
54
+ typedef bool (*handshake)(connection* c, void* data);
52
55
  class connections
53
56
  {
54
57
  std::vector<connection*> m_conns;
55
58
  boost::asio::io_service m_ios;
56
-
57
59
  mutex m_mutex;
60
+ std::string m_pipeName;
61
+ static bool m_usePipedLocal;
58
62
 
59
63
  connection* getConnection(asio::ip::tcp::endpoint& ep);
60
64
  asio::ip::tcp::endpoint endpoint(const std::string& host,
61
65
  boost::system::error_code& ec);
62
-
63
66
  bool isUseNamedPipe(asio::ip::tcp::endpoint& ep);
64
-
65
- static bool m_usePipedLocal;
66
-
67
- std::string m_pipeName;
68
67
  #ifdef USE_PIPE_CLIENT
69
68
  connection* getConnectionPipe();
70
69
  #endif
71
-
70
+ inline connection* doConnect(connection* c);
71
+ inline connection* createConnection(asio::ip::tcp::endpoint& ep, bool namedPipe);
72
+ inline bool doHandShake(connection* c, handshake f, void* data);
72
73
  public:
73
74
  connections(const char* pipeName);
74
75
  ~connections();
75
- connection* connect(const std::string& host, bool newConnection = false);
76
+ connection* connect(const std::string& host, handshake f,
77
+ void* data, bool newConnection = false);
76
78
  connection* getConnection(const std::string& host);
77
-
78
79
  bool disconnect(connection* c);
79
-
80
+ int connectionCount();
80
81
  static char port[PORTNUMBUF_SIZE];
81
82
  static short timeout;
82
-
83
- int connectionCount();
84
83
  };
85
84
 
86
85
  /** Implementation of Part of the connection interface
@@ -97,10 +96,9 @@ protected:
97
96
  idirectReadHandler* m_reader;
98
97
  size_t m_readLen;
99
98
  int m_refCount;
100
- thread_id m_tid;
101
99
  int m_charsetServer;
102
100
  bool m_connected;
103
-
101
+ bool m_isHandShakable;
104
102
 
105
103
  void addref() { ++m_refCount; }
106
104
 
@@ -112,16 +110,14 @@ protected:
112
110
 
113
111
  const asio::ip::tcp::endpoint& endpoint() const { return m_ep; }
114
112
 
115
- thread_id tid() const { return m_tid; };
116
-
117
113
  int charsetServer() const { return m_charsetServer; };
118
114
 
119
115
  void setCharsetServer(int v) { m_charsetServer = v; }
120
116
 
121
117
  public:
122
118
  connectionBase(asio::ip::tcp::endpoint& ep)
123
- : m_ep(ep), m_reader(NULL), m_refCount(0), m_tid(threadid()),
124
- m_charsetServer(-1), m_connected(false)
119
+ : m_ep(ep), m_reader(NULL), m_refCount(0),
120
+ m_charsetServer(-1), m_connected(false), m_isHandShakable(true)
125
121
  {
126
122
  }
127
123
 
@@ -132,7 +128,7 @@ public:
132
128
  if (size > m_sendbuf.size())
133
129
  m_sendbuf.resize(size);
134
130
  return &m_sendbuf[0];
135
- };
131
+ }
136
132
 
137
133
  unsigned int sendBufferSize() { return (unsigned int)m_sendbuf.size(); };
138
134
 
@@ -141,12 +137,17 @@ public:
141
137
  if (m_readbuf.size() < size)
142
138
  m_readbuf.resize(size);
143
139
  }
140
+
141
+ bool isHandShakable() const {return m_isHandShakable;};
144
142
  };
145
143
 
146
144
  /** Implementation of the connection template
147
145
  */
148
146
  template <class T> class connectionImple : public connectionBase
149
147
  {
148
+ #ifdef LINUX
149
+ sigset_t m_signmask, m_sigomask;
150
+ #endif
150
151
  protected:
151
152
  //unsigned int m_datalen;
152
153
  //unsigned short m_rows;
@@ -210,11 +211,25 @@ protected:
210
211
  return &m_readbuf[0];
211
212
  }
212
213
 
213
- void read()
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
+
229
+ char* read()
214
230
  {
215
231
  if (!m_connected)
216
232
  throw system_error(asio::error::not_connected);
217
- boost::system::error_code e;
218
233
  m_readLen = 0;
219
234
  //m_datalen = 0;
220
235
  //m_rows = 0;
@@ -230,26 +245,23 @@ protected:
230
245
  }*/
231
246
  if (m_reader)
232
247
  {
233
- m_readLen = boost::asio::read(m_socket, boost::asio::buffer(&n, 4),
234
- boost::asio::transfer_all());
248
+ m_readLen = doRead(boost::asio::buffer(&n, 4), boost::asio::transfer_all());
249
+
235
250
  m_readLen += m_reader->onRead(n - 4, this);
236
251
  }else
237
252
  {
238
- m_readLen = boost::asio::read(m_socket,
239
- boost::asio::buffer(&m_readbuf[0],m_readbuf.size()),
240
- boost::asio::transfer_at_least(4));
253
+ m_readLen = doRead(boost::asio::buffer(&m_readbuf[0],m_readbuf.size()),
254
+ boost::asio::transfer_at_least(4));
241
255
  n = *((unsigned int*)(&m_readbuf[0]));
242
256
  }
243
- if (m_readLen < n)
257
+ if ((n > m_readLen) && (n < MAX_DATA_SIZE))
244
258
  {
245
259
  if (n > m_readbuf.size())
246
260
  m_readbuf.resize(n);
247
-
248
- m_readLen += boost::asio::read(
249
- m_socket,
250
- boost::asio::buffer(&m_readbuf[m_readLen], n - m_readLen),
251
- boost::asio::transfer_all());
261
+ m_readLen += doRead(boost::asio::buffer(&m_readbuf[m_readLen], n - m_readLen),
262
+ boost::asio::transfer_all());
252
263
  }
264
+ return &m_readbuf[0];
253
265
  }
254
266
 
255
267
  void write(unsigned int writeSize)
@@ -273,11 +285,13 @@ public:
273
285
  connectionImple(asio::ip::tcp::endpoint& ep)
274
286
  : connectionBase(ep)/*, m_datalen(0)*/, m_socket(m_ios)
275
287
  {
288
+ #ifdef LINUX
289
+ sigfillset(&m_signmask);
290
+ #endif
276
291
  }
277
292
 
278
293
  ~connectionImple()
279
294
  {
280
-
281
295
  try
282
296
  {
283
297
  m_ios.stop();
@@ -291,8 +305,7 @@ public:
291
305
  char* asyncWriteRead(unsigned int writeSize)
292
306
  {
293
307
  write(writeSize);
294
- read();
295
- return &m_readbuf[0];
308
+ return read();
296
309
  }
297
310
 
298
311
  buffers* optionalBuffers() { return &m_optionalBuffes; }
@@ -336,8 +349,6 @@ public:
336
349
  setupTimeouts();
337
350
  m_socket.connect(m_ep);
338
351
  m_socket.set_option(boost::asio::ip::tcp::no_delay(true));
339
- char tmp[20];
340
- m_socket.read_some(boost::asio::buffer(tmp, 10));
341
352
  m_connected = true;
342
353
  }
343
354
  };
@@ -453,6 +464,28 @@ class pipeConnection : public connectionImple<platform_stream>
453
464
  throwException("OpenEvent Server", CLIENT_ERROR_SHAREMEM_DENIED);
454
465
  }
455
466
 
467
+ void write(unsigned int writeSize)
468
+ {
469
+ //m_datalen = 0;
470
+ //m_rows = 0;
471
+ BOOL ret = SetEvent(m_sendEvent);
472
+ if (ret == FALSE)
473
+ throwException("SetEvent", CLIENT_ERROR_CONNECTION_FAILURE);
474
+ }
475
+
476
+ char* read()
477
+ {
478
+ while (WAIT_TIMEOUT == WaitForSingleObject(m_recvEvent, connections::timeout))
479
+ {
480
+ DWORD n = 0;
481
+ BOOL ret = GetNamedPipeHandleState(m_socket.native(), NULL, &n,
482
+ NULL, NULL, NULL, 0);
483
+ if(ret == FALSE || n == 0)
484
+ throwException("PipeConnection", CLIENT_ERROR_CONNECTION_FAILURE);
485
+ }
486
+ return m_readbuf_p;
487
+ }
488
+
456
489
  public:
457
490
  pipeConnection(asio::ip::tcp::endpoint& ep, const std::string& pipeName)
458
491
  : connectionImple<platform_stream>(ep), m_pipeName(pipeName),
@@ -464,11 +497,22 @@ public:
464
497
 
465
498
  ~pipeConnection()
466
499
  {
467
- memset(m_writebuf_p, 0, sizeof(unsigned int));
468
-
469
- SetEvent(m_sendEvent);
470
- WaitForSingleObject(m_recvEvent, INFINITE);
471
-
500
+ if (m_connected)
501
+ {
502
+ if (m_writebuf_p)
503
+ memset(m_writebuf_p, 0, sizeof(unsigned int));
504
+ DWORD n = 0;
505
+ BOOL ret = GetNamedPipeHandleState(m_socket.native(), NULL, &n,
506
+ NULL, NULL, NULL, 0);
507
+ if(m_sendEvent && ret && n)
508
+ {
509
+ SetEvent(m_sendEvent);
510
+ //Wait for server side close connection
511
+ while (WAIT_TIMEOUT ==
512
+ WaitForSingleObject(m_recvEvent, connections::timeout))
513
+ ;
514
+ }
515
+ }
472
516
  if (m_recvEvent)
473
517
  CloseHandle(m_recvEvent);
474
518
  if (m_sendEvent)
@@ -504,35 +548,23 @@ public:
504
548
  m_socket.assign(fd);
505
549
  m_connected = true;
506
550
 
507
- // send processId;
508
-
551
+ // send processId and clientid;
509
552
  DWORD processId = GetCurrentProcessId();
510
553
  int size = 16;
511
- connectionBase::m_readbuf.resize(size);
554
+ connectionBase::m_readbuf.resize(256);
512
555
  char* p = &connectionBase::m_readbuf[0];
513
556
  memcpy(p, &size, sizeof(int));
514
557
  memcpy(p + 4, &processId, sizeof(DWORD));
515
558
  __int64 clientid = (__int64) this;
516
559
  memcpy(p + 8, &clientid, sizeof(__int64));
517
560
  boost::asio::write(m_socket, boost::asio::buffer(p, size));
561
+
518
562
  boost::asio::read(m_socket, boost::asio::buffer(p, 7));
519
- unsigned int* shareMemSize = (unsigned int*)(p + 3);
563
+ unsigned int* shareMemSize = (unsigned int*)(p+3);
564
+ m_isHandShakable = (p[0] == 0x00);
520
565
  createKernelObjects(*shareMemSize);
521
566
  }
522
567
 
523
- char* asyncWriteRead(unsigned int writeSize)
524
- {
525
- //m_datalen = 0;
526
- //m_rows = 0;
527
- BOOL ret = SetEvent(m_sendEvent);
528
- if (ret == FALSE)
529
- throwException("SetEvent", CLIENT_ERROR_CONNECTION_FAILURE);
530
- DWORD r = WaitForSingleObject(m_recvEvent, connections::timeout);
531
- if (r == WAIT_TIMEOUT)
532
- throwException("SetEvent", CLIENT_ERROR_CONNECTION_FAILURE);
533
- return m_readbuf_p;
534
- }
535
-
536
568
  char* sendBuffer(size_t size) { return m_writebuf_p; }
537
569
 
538
570
  unsigned int sendBufferSize() { return m_sendBufferSize; }
@@ -45,7 +45,7 @@ class iconnection;
45
45
  #define EXECUTE_RESULT_QUIT 1
46
46
  #define EXECUTE_RESULT_FORCSE_ASYNC 2
47
47
  #define EXECUTE_RESULT_FORCSE_SYNC 3
48
-
48
+ #define EXECUTE_RESULT_ACCESS_DNIED 4
49
49
  typedef std::vector<boost::asio::const_buffer> buffers;
50
50
  typedef std::vector<char> vector_buffer;
51
51
 
@@ -80,7 +80,7 @@ public:
80
80
  virtual size_t onAccept(char* message, size_t bufsize) = 0;
81
81
  virtual void reset() = 0;
82
82
  virtual bool isShutDown() = 0;
83
- virtual bool checkHost(const char* hostCheckname) = 0;
83
+ virtual bool checkHost(const char* hostCheckname, /*out*/char* hostName, int size) = 0;
84
84
  virtual void cleanup() = 0;
85
85
  virtual boost::mutex& mutex() const = 0;
86
86
  };