transactd 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
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
  };