transactd 1.0.1

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 (218) hide show
  1. checksums.yaml +7 -0
  2. data/BUILD_UNIX-JA +174 -0
  3. data/BUILD_WIN-JA +256 -0
  4. data/CMakeLists.txt +96 -0
  5. data/COPYING +339 -0
  6. data/README +406 -0
  7. data/README-JA +424 -0
  8. data/bin/common/tdclc_32_1_0.dll +0 -0
  9. data/bin/common/tdclc_64_1_0.dll +0 -0
  10. data/build/common/check_for_link_iconv.cmake +73 -0
  11. data/build/common/copyifgreater.cmd +30 -0
  12. data/build/common/copyifgreater.js +290 -0
  13. data/build/common/get_boost_libs.cmake +106 -0
  14. data/build/common/get_ruby_path.cmake +115 -0
  15. data/build/common/options.cmake +127 -0
  16. data/build/common/smart_install.cmake +263 -0
  17. data/build/common/system.cmake +122 -0
  18. data/build/common/transactd.rc.in +52 -0
  19. data/build/common/transactd_cl_common.cmake +101 -0
  20. data/build/common/transactd_cl_output.cmake +93 -0
  21. data/build/common/transactd_common.cmake +237 -0
  22. data/build/common/transactd_required.cmake +28 -0
  23. data/build/swig/ruby/generate.cmake.in +35 -0
  24. data/build/swig/ruby/generate.cmd.in +19 -0
  25. data/build/swig/ruby/ruby.swg +101 -0
  26. data/build/swig/tdcl.i +188 -0
  27. data/build/tdclc/BUILDNUMBER.txt +1 -0
  28. data/build/tdclc/CMakeLists.txt +170 -0
  29. data/build/tdclc/tdclc_32.cbproj +181 -0
  30. data/build/tdclc/tdclc_64.cbproj +205 -0
  31. data/build/tdclcpp/BUILDNUMBER.txt +1 -0
  32. data/build/tdclcpp/CMakeLists.txt +142 -0
  33. data/build/tdclcpp/tdclcpp_bcb_32.cbproj +239 -0
  34. data/build/tdclcpp/tdclcpp_bcb_64.cbproj +304 -0
  35. data/build/tdclrb/BUILDNUMBER.txt +1 -0
  36. data/build/tdclrb/CMakeLists.txt +258 -0
  37. data/build/tdclrb/GEM_VERSION +3 -0
  38. data/build/tdclrb/bldgem/extconf.rb +123 -0
  39. data/build/tdclrb/gem/INSTALLLOG.win32 +9 -0
  40. data/build/tdclrb/gem/Makefile.win32-VS +65 -0
  41. data/build/tdclrb/gem/Makefile.win32-prebuilt +48 -0
  42. data/build/tdclrb/gem/detect.rb +31 -0
  43. data/build/tdclrb/gem/helper.rb +113 -0
  44. data/build/tdclrb/gem/transactd.rb +22 -0
  45. data/build/tdclrb/gem_output.cmake +44 -0
  46. data/source/bzs/db/IBlobBuffer.h +51 -0
  47. data/source/bzs/db/blobBuffer.h +177 -0
  48. data/source/bzs/db/blobStructs.h +85 -0
  49. data/source/bzs/db/engine/mysql/IReadRecords.h +52 -0
  50. data/source/bzs/db/engine/mysql/bookmark.h +195 -0
  51. data/source/bzs/db/engine/mysql/database.cpp +1882 -0
  52. data/source/bzs/db/engine/mysql/database.h +465 -0
  53. data/source/bzs/db/engine/mysql/dbManager.cpp +303 -0
  54. data/source/bzs/db/engine/mysql/dbManager.h +143 -0
  55. data/source/bzs/db/engine/mysql/errorMessage.cpp +75 -0
  56. data/source/bzs/db/engine/mysql/errorMessage.h +43 -0
  57. data/source/bzs/db/engine/mysql/fieldAccess.h +158 -0
  58. data/source/bzs/db/engine/mysql/mydebuglog.cpp +349 -0
  59. data/source/bzs/db/engine/mysql/mydebuglog.h +89 -0
  60. data/source/bzs/db/engine/mysql/mysqlInternal.h +171 -0
  61. data/source/bzs/db/engine/mysql/mysqlThd.cpp +169 -0
  62. data/source/bzs/db/engine/mysql/mysqlThd.h +35 -0
  63. data/source/bzs/db/engine/mysql/percentageKey.h +260 -0
  64. data/source/bzs/db/protocol/ICommandExecuter.h +49 -0
  65. data/source/bzs/db/protocol/hs/hsCommandExecuter.cpp +689 -0
  66. data/source/bzs/db/protocol/hs/hsCommandExecuter.h +228 -0
  67. data/source/bzs/db/protocol/tdap/btrDate.cpp +437 -0
  68. data/source/bzs/db/protocol/tdap/btrDate.h +227 -0
  69. data/source/bzs/db/protocol/tdap/client/bulkInsert.h +127 -0
  70. data/source/bzs/db/protocol/tdap/client/client.cpp +106 -0
  71. data/source/bzs/db/protocol/tdap/client/client.h +292 -0
  72. data/source/bzs/db/protocol/tdap/client/connMgr.cpp +144 -0
  73. data/source/bzs/db/protocol/tdap/client/connMgr.h +82 -0
  74. data/source/bzs/db/protocol/tdap/client/database.cpp +863 -0
  75. data/source/bzs/db/protocol/tdap/client/database.h +118 -0
  76. data/source/bzs/db/protocol/tdap/client/databaseFactory.cpp +100 -0
  77. data/source/bzs/db/protocol/tdap/client/dbDef.cpp +1640 -0
  78. data/source/bzs/db/protocol/tdap/client/dbDef.h +135 -0
  79. data/source/bzs/db/protocol/tdap/client/dllmain.cpp +434 -0
  80. data/source/bzs/db/protocol/tdap/client/errorMessage.cpp +92 -0
  81. data/source/bzs/db/protocol/tdap/client/errorMessage_ja.cpp +98 -0
  82. data/source/bzs/db/protocol/tdap/client/fieldDDF.cpp +174 -0
  83. data/source/bzs/db/protocol/tdap/client/fieldDDF.h +91 -0
  84. data/source/bzs/db/protocol/tdap/client/fileDDF.cpp +140 -0
  85. data/source/bzs/db/protocol/tdap/client/fileDDF.h +86 -0
  86. data/source/bzs/db/protocol/tdap/client/filter.cpp +527 -0
  87. data/source/bzs/db/protocol/tdap/client/filter.h +154 -0
  88. data/source/bzs/db/protocol/tdap/client/indexDDF.cpp +137 -0
  89. data/source/bzs/db/protocol/tdap/client/indexDDF.h +84 -0
  90. data/source/bzs/db/protocol/tdap/client/nsDatabase.cpp +724 -0
  91. data/source/bzs/db/protocol/tdap/client/nsDatabase.h +123 -0
  92. data/source/bzs/db/protocol/tdap/client/nsTable.cpp +899 -0
  93. data/source/bzs/db/protocol/tdap/client/nsTable.h +199 -0
  94. data/source/bzs/db/protocol/tdap/client/request.h +198 -0
  95. data/source/bzs/db/protocol/tdap/client/sharedData.cpp +58 -0
  96. data/source/bzs/db/protocol/tdap/client/sharedData.h +56 -0
  97. data/source/bzs/db/protocol/tdap/client/sqlBuilder.cpp +574 -0
  98. data/source/bzs/db/protocol/tdap/client/sqlBuilder.h +53 -0
  99. data/source/bzs/db/protocol/tdap/client/stringConverter.h +627 -0
  100. data/source/bzs/db/protocol/tdap/client/table.cpp +2613 -0
  101. data/source/bzs/db/protocol/tdap/client/table.h +221 -0
  102. data/source/bzs/db/protocol/tdap/client/trdboostapi.h +1096 -0
  103. data/source/bzs/db/protocol/tdap/client/trdboostapiInternal.h +179 -0
  104. data/source/bzs/db/protocol/tdap/client/trdclcppautolink.h +40 -0
  105. data/source/bzs/db/protocol/tdap/client/trnsctcl.def +11 -0
  106. data/source/bzs/db/protocol/tdap/myDateTime.cpp +500 -0
  107. data/source/bzs/db/protocol/tdap/mysql/characterset.cpp +184 -0
  108. data/source/bzs/db/protocol/tdap/mysql/characterset.h +60 -0
  109. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.cpp +284 -0
  110. data/source/bzs/db/protocol/tdap/mysql/databaseSchema.h +53 -0
  111. data/source/bzs/db/protocol/tdap/mysql/debuglog.cpp +383 -0
  112. data/source/bzs/db/protocol/tdap/mysql/debuglog.h +106 -0
  113. data/source/bzs/db/protocol/tdap/mysql/recordsetReader.h +680 -0
  114. data/source/bzs/db/protocol/tdap/mysql/request.h +202 -0
  115. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.cpp +1020 -0
  116. data/source/bzs/db/protocol/tdap/mysql/tdapCommandExecuter.h +141 -0
  117. data/source/bzs/db/protocol/tdap/tdapRequest.h +190 -0
  118. data/source/bzs/db/protocol/tdap/tdapSchema.cpp +295 -0
  119. data/source/bzs/db/protocol/tdap/tdapSchema.h +558 -0
  120. data/source/bzs/db/protocol/tdap/tdapcapi.h +423 -0
  121. data/source/bzs/db/transactd/appBuilderImple.h +55 -0
  122. data/source/bzs/db/transactd/appModule.cpp +183 -0
  123. data/source/bzs/db/transactd/appModule.h +80 -0
  124. data/source/bzs/db/transactd/connManager.cpp +201 -0
  125. data/source/bzs/db/transactd/connManager.h +60 -0
  126. data/source/bzs/db/transactd/connectionRecord.h +69 -0
  127. data/source/bzs/db/transactd/transactd.cpp +325 -0
  128. data/source/bzs/env/compiler.h +135 -0
  129. data/source/bzs/env/crosscompile.cpp +130 -0
  130. data/source/bzs/env/crosscompile.h +150 -0
  131. data/source/bzs/env/fileopen.h +36 -0
  132. data/source/bzs/env/mbcswchrLinux.cpp +40 -0
  133. data/source/bzs/env/mbcswchrLinux.h +88 -0
  134. data/source/bzs/env/tstring.h +183 -0
  135. data/source/bzs/example/changeSchema.cpp +117 -0
  136. data/source/bzs/example/changeSchema_c.cpp +78 -0
  137. data/source/bzs/example/connection_pool_c.cpp +171 -0
  138. data/source/bzs/example/createDatabase.cpp +305 -0
  139. data/source/bzs/example/createDatabase_c.cpp +202 -0
  140. data/source/bzs/example/deleteRecords.cpp +87 -0
  141. data/source/bzs/example/deleteRecords_c.cpp +57 -0
  142. data/source/bzs/example/dropDatabase.cpp +59 -0
  143. data/source/bzs/example/dropDatabase_c.cpp +34 -0
  144. data/source/bzs/example/insertRecords.cpp +212 -0
  145. data/source/bzs/example/insertRecords_c.cpp +153 -0
  146. data/source/bzs/example/readRecords.cpp +141 -0
  147. data/source/bzs/example/readRecords_c.cpp +107 -0
  148. data/source/bzs/example/updateRecords.cpp +99 -0
  149. data/source/bzs/example/updateRecords_c.cpp +71 -0
  150. data/source/bzs/example/update_with_transaction.cpp +104 -0
  151. data/source/bzs/example/update_with_transaction_c.cpp +80 -0
  152. data/source/bzs/netsvc/client/tcpClient.cpp +226 -0
  153. data/source/bzs/netsvc/client/tcpClient.h +489 -0
  154. data/source/bzs/netsvc/server/IAppModule.h +94 -0
  155. data/source/bzs/netsvc/server/iserver.h +65 -0
  156. data/source/bzs/netsvc/server/serverCpt.cpp +522 -0
  157. data/source/bzs/netsvc/server/serverCpt.h +88 -0
  158. data/source/bzs/netsvc/server/serverPipe.cpp +705 -0
  159. data/source/bzs/netsvc/server/serverPipe.h +96 -0
  160. data/source/bzs/netsvc/server/serverTpool.cpp +416 -0
  161. data/source/bzs/netsvc/server/serverTpool.h +84 -0
  162. data/source/bzs/rtl/benchmark.cpp +96 -0
  163. data/source/bzs/rtl/benchmark.h +65 -0
  164. data/source/bzs/rtl/datetime.cpp +375 -0
  165. data/source/bzs/rtl/datetime.h +53 -0
  166. data/source/bzs/rtl/debuglog.cpp +106 -0
  167. data/source/bzs/rtl/debuglog.h +97 -0
  168. data/source/bzs/rtl/exception.h +116 -0
  169. data/source/bzs/rtl/stl_uty.cpp +35 -0
  170. data/source/bzs/rtl/stl_uty.h +29 -0
  171. data/source/bzs/rtl/stringBuffers.cpp +101 -0
  172. data/source/bzs/rtl/stringBuffers.h +58 -0
  173. data/source/bzs/rtl/strtrim.cpp +135 -0
  174. data/source/bzs/rtl/strtrim.h +46 -0
  175. data/source/bzs/test/tdclatl/bench_tdclatl.js +445 -0
  176. data/source/bzs/test/tdclrb/bench_tdclcpp.rb +375 -0
  177. data/source/bzs/test/tdclrb/prepare.rb +226 -0
  178. data/source/bzs/test/tdclrb/transactd_datetime_spec.rb +172 -0
  179. data/source/bzs/test/tdclrb/transactd_kanjischema_spec.rb +208 -0
  180. data/source/bzs/test/tdclrb/transactd_spec.rb +1536 -0
  181. data/source/bzs/test/transactdBench/transactdBench.cpp +430 -0
  182. data/source/bzs/test/transactdBench/transactdBench2.cpp +342 -0
  183. data/source/bzs/test/trdclengn/test_trdclengn.cpp +2030 -0
  184. data/source/global/tdclatl/Database.cpp +503 -0
  185. data/source/global/tdclatl/Database.h +139 -0
  186. data/source/global/tdclatl/DbDef.cpp +242 -0
  187. data/source/global/tdclatl/DbDef.h +79 -0
  188. data/source/global/tdclatl/Field.cpp +92 -0
  189. data/source/global/tdclatl/Field.h +59 -0
  190. data/source/global/tdclatl/FieldDef.cpp +238 -0
  191. data/source/global/tdclatl/FieldDef.h +87 -0
  192. data/source/global/tdclatl/Flags.cpp +111 -0
  193. data/source/global/tdclatl/Flags.h +55 -0
  194. data/source/global/tdclatl/KeyDef.cpp +51 -0
  195. data/source/global/tdclatl/KeyDef.h +55 -0
  196. data/source/global/tdclatl/KeySegment.cpp +55 -0
  197. data/source/global/tdclatl/Table.cpp +600 -0
  198. data/source/global/tdclatl/Table.h +144 -0
  199. data/source/global/tdclatl/TableDef.cpp +291 -0
  200. data/source/global/tdclatl/TableDef.h +86 -0
  201. data/source/global/tdclatl/TdVersion.cpp +74 -0
  202. data/source/global/tdclatl/TdVersion.h +54 -0
  203. data/source/global/tdclatl/_IDatabaseEvents_CP.h +113 -0
  204. data/source/global/tdclatl/dllmain.cpp +30 -0
  205. data/source/global/tdclatl/dllmain.h +27 -0
  206. data/source/global/tdclatl/keySegment.h +57 -0
  207. data/source/global/tdclatl/resource.h +0 -0
  208. data/source/global/tdclatl/stdafx.cpp +2 -0
  209. data/source/global/tdclatl/stdafx.h +25 -0
  210. data/source/global/tdclatl/targetver.h +4 -0
  211. data/source/global/tdclatl/tdclatl.cpp +68 -0
  212. data/source/global/tdclatl/tdclatl.def +10 -0
  213. data/source/global/tdclatl/tdclatl.idl +1035 -0
  214. data/source/linux/charsetConvert.h +112 -0
  215. data/source/linux/linuxTypes.h +33 -0
  216. data/source/linux/tchar.h +428 -0
  217. data/transactd.gemspec +97 -0
  218. metadata +267 -0
@@ -0,0 +1,705 @@
1
+ /*=================================================================
2
+ Copyright (C) 2012 2013 BizStation Corp All rights reserved.
3
+
4
+ This program is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU General Public License
6
+ as published by the Free Software Foundation; either version 2
7
+ of the License, or (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program; if not, write to the Free Software
16
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17
+ 02111-1307, USA.
18
+ =================================================================*/
19
+
20
+ #include "serverPipe.h"
21
+ #include <boost/bind.hpp>
22
+ #include <boost/array.hpp>
23
+ #include <boost/shared_ptr.hpp>
24
+ #include <boost/scoped_array.hpp>
25
+ #include <boost/thread.hpp>
26
+ #include <boost/asio/write.hpp>
27
+ #include <boost/thread/xtime.hpp>
28
+ #include <algorithm>
29
+ #include <boost/enable_shared_from_this.hpp>
30
+ #include "IAppModule.h"
31
+ #include <bzs/rtl/exception.h>
32
+
33
+
34
+
35
+ using namespace boost;
36
+ using namespace boost::asio;
37
+ using namespace boost::asio::ip;
38
+
39
+
40
+
41
+ char* getWindowsErrMsg( DWORD ErrorCode)
42
+ {
43
+ LPVOID lpMsgBuf;
44
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
45
+ NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
46
+ (LPSTR) &lpMsgBuf, 0, NULL);
47
+ return (char*)lpMsgBuf;
48
+ }
49
+
50
+ #define PIPE_EOF_ERROR_CODE boost::system::windows_error::broken_pipe
51
+ #define BUFSIZE 0
52
+
53
+
54
+ namespace bzs
55
+ {
56
+ namespace netsvc
57
+ {
58
+ namespace server
59
+ {
60
+ namespace pipe
61
+ {
62
+
63
+ void getSecurityAttribute(SECURITY_ATTRIBUTES& sa, SECURITY_DESCRIPTOR& sd)
64
+ {
65
+
66
+ InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
67
+ SetSecurityDescriptorDacl(&sd,TRUE, NULL,FALSE);
68
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
69
+ sa.bInheritHandle = TRUE;
70
+ sa.lpSecurityDescriptor = &sd;
71
+ }
72
+
73
+ acceptor::acceptor():m_fd(0),m_cancel(false)
74
+ {
75
+
76
+ }
77
+
78
+ void acceptor::open(const std::string& pipeName)
79
+ {
80
+ m_pipeName = pipeName;
81
+ }
82
+
83
+ void acceptor::cancel()
84
+ {
85
+ m_cancel = true;
86
+ }
87
+
88
+ void acceptor::accept(platform_stream& pipe)
89
+ {
90
+ m_fd=NULL;
91
+ SECURITY_DESCRIPTOR sd;
92
+ SECURITY_ATTRIBUTES sa;
93
+ getSecurityAttribute(sa, sd);
94
+
95
+ char pipeName[100];
96
+ sprintf_s(pipeName, 100, "\\\\.\\pipe\\%s", m_pipeName.c_str());
97
+ m_fd = CreateNamedPipe( pipeName, // pipe name
98
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED
99
+ ,PIPE_TYPE_BYTE |PIPE_READMODE_BYTE |PIPE_WAIT
100
+ ,PIPE_UNLIMITED_INSTANCES // max. instances
101
+ ,BUFSIZE // output buffer size
102
+ ,BUFSIZE // input buffer size
103
+ ,0 // client time-out
104
+ ,&sa); // default security attribute
105
+ if (m_fd == INVALID_HANDLE_VALUE)
106
+ THROW_BZS_ERROR_WITH_MSG(getWindowsErrMsg(GetLastError()));
107
+ OVERLAPPED overlapped = {0};
108
+ overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0);
109
+ BOOL ret = ConnectNamedPipe(m_fd, &overlapped);
110
+
111
+ //Connection may be completed by timing at this time.
112
+ if ((ret==FALSE) && (GetLastError() == ERROR_PIPE_CONNECTED))
113
+ {
114
+ CloseHandle(overlapped.hEvent);
115
+ pipe.assign(m_fd);
116
+ return;
117
+ }
118
+ if ((ret != FALSE) || (GetLastError() != ERROR_IO_PENDING))
119
+ {
120
+ CloseHandle(overlapped.hEvent);
121
+ CloseHandle(m_fd);
122
+ THROW_BZS_ERROR_WITH_MSG("ConnectNamedPipe error");
123
+ return ;
124
+ }
125
+
126
+ //A shutdown is supervised periodically.
127
+ DWORD waitRes;
128
+ while (1)
129
+ {
130
+ if (m_cancel)
131
+ {
132
+ CloseHandle(overlapped.hEvent);
133
+ CloseHandle(m_fd);
134
+ break;
135
+ }
136
+ waitRes = WaitForSingleObject(overlapped.hEvent, 5);
137
+ if (waitRes == WAIT_OBJECT_0)
138
+ {
139
+ CloseHandle(overlapped.hEvent);
140
+ pipe.assign(m_fd);
141
+ break;
142
+ }else if (waitRes == WAIT_TIMEOUT)
143
+ ;
144
+ else
145
+ {
146
+ CloseHandle(overlapped.hEvent);
147
+ CloseHandle(m_fd);
148
+ THROW_BZS_ERROR_WITH_MSG("WaitForSingleObject error");
149
+ }
150
+ }
151
+ }
152
+
153
+ unsigned int g_connections=0;
154
+ unsigned int g_waitThread=0;
155
+
156
+
157
+ // ---------------------------------------------------------------------------
158
+ // connection
159
+ // ---------------------------------------------------------------------------
160
+
161
+
162
+
163
+ class IExitCheckHandler
164
+ {
165
+ public:
166
+ virtual ~IExitCheckHandler(){};
167
+ virtual bool isExit()=0;
168
+ };
169
+
170
+
171
+ class exitCheckHnadler : public IExitCheckHandler
172
+ {
173
+ HANDLE m_thread;
174
+ bool m_cancel;
175
+ IAppModule* m_module;
176
+ public:
177
+
178
+ exitCheckHnadler(DWORD tid):m_cancel(false),m_module(NULL)
179
+ {
180
+ m_thread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION /*THREAD_QUERY_INFORMATION*/, FALSE, tid);
181
+ /*if (!m_thread)
182
+ {
183
+ char buf[1024];
184
+ wsprintf(buf, "OpenThread error :id = %d %s", tid, getWindowsErrMsg(GetLastError()));
185
+ THROW_BZS_ERROR_WITH_MSG(buf);
186
+ }*/
187
+ }
188
+
189
+ ~exitCheckHnadler()
190
+ {
191
+ if (m_thread)
192
+ CloseHandle(m_thread);
193
+ }
194
+
195
+ void setModule(IAppModule* p)
196
+ {
197
+ m_module = p;
198
+ }
199
+
200
+ bool isExit()
201
+ {
202
+ if (m_cancel)return true;
203
+ DWORD ExitCode;
204
+ if (m_thread && GetExitCodeThread(m_thread, &ExitCode))
205
+ if (STILL_ACTIVE!=ExitCode) return true;
206
+ if (m_module && m_module->isShutDown())
207
+ return true;
208
+ return false;
209
+ }
210
+
211
+ void setCancel(bool value){m_cancel=value;};
212
+ bool cancel(){return m_cancel;}
213
+ };
214
+
215
+ class winEventComm
216
+ {
217
+ HANDLE m_recv;
218
+ HANDLE m_send;
219
+ bool m_sent;
220
+ bool m_cancel;
221
+ public:
222
+
223
+ winEventComm(const char* rcvName, const char* sndName):m_cancel(false)
224
+ {
225
+ SECURITY_DESCRIPTOR sd;
226
+ SECURITY_ATTRIBUTES sa;
227
+ getSecurityAttribute(sa, sd);
228
+ m_recv = CreateEvent(&sa, FALSE, FALSE, rcvName);
229
+ if (!m_recv)
230
+ THROW_BZS_ERROR_WITH_MSG(getWindowsErrMsg(GetLastError()));
231
+ m_send = CreateEvent(&sa, FALSE, FALSE, sndName);
232
+ if (!m_send)
233
+ THROW_BZS_ERROR_WITH_MSG(getWindowsErrMsg(GetLastError()));
234
+ }
235
+
236
+ ~winEventComm()
237
+ {
238
+ if (!m_sent)SetEvent(m_send);
239
+ if (m_recv)CloseHandle(m_recv);
240
+ if (m_send)CloseHandle(m_send);
241
+ }
242
+
243
+ bool recv(int checkTimeSpan, IExitCheckHandler* handler)
244
+ {
245
+ DWORD wait;
246
+ do{
247
+ if (m_cancel || (handler && (handler->isExit())))
248
+ return 0;
249
+ }while(WAIT_OBJECT_0 != (wait = WaitForSingleObject(m_recv, checkTimeSpan)));
250
+ m_sent = false;
251
+ return true;
252
+ }
253
+
254
+ bool send()
255
+ {
256
+ if (SetEvent(m_send)==0)
257
+ return false;
258
+
259
+ m_sent = true;
260
+ return true;
261
+ }
262
+
263
+ void chancel(){m_cancel = true;}
264
+ };
265
+
266
+ class sharedMem
267
+ {
268
+ HANDLE m_mapFile;
269
+
270
+ char* m_readPtr;
271
+ char* m_writePtr;
272
+ public:
273
+
274
+ sharedMem(const char* name, unsigned int memsize)
275
+ {
276
+ SECURITY_DESCRIPTOR sd;
277
+ SECURITY_ATTRIBUTES sa;
278
+ getSecurityAttribute(sa, sd);
279
+
280
+ SYSTEM_INFO SystemInfo;
281
+ GetSystemInfo(&SystemInfo);
282
+ int size = memsize/SystemInfo.dwAllocationGranularity + 1;
283
+ size = size*SystemInfo.dwAllocationGranularity;
284
+
285
+
286
+ m_mapFile = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, size*2, name);
287
+ if (m_mapFile == NULL)
288
+ THROW_BZS_ERROR_WITH_MSG("CreateFileMapping error");
289
+
290
+ m_readPtr = (char*)MapViewOfFile(m_mapFile, FILE_MAP_ALL_ACCESS, 0, 0, size);
291
+ if (m_readPtr == NULL)
292
+ THROW_BZS_ERROR_WITH_MSG("MapViewOfFile R error");
293
+ m_writePtr = (char*)MapViewOfFile(m_mapFile, FILE_MAP_ALL_ACCESS, 0, size, size);
294
+ if (m_writePtr == NULL)
295
+ THROW_BZS_ERROR_WITH_MSG("MapViewOfFile W error");
296
+ }
297
+
298
+ ~sharedMem()
299
+ {
300
+ if (m_mapFile)
301
+ {
302
+ UnmapViewOfFile(m_readPtr) ;
303
+ UnmapViewOfFile(m_writePtr) ;
304
+ CloseHandle(m_mapFile);
305
+ }
306
+ }
307
+
308
+ char* readBuffer()
309
+ {
310
+ return m_readPtr;
311
+ }
312
+
313
+ char* writeBuffer()
314
+ {
315
+ return m_writePtr;
316
+ }
317
+ };
318
+
319
+ class connection : public iconnection, private noncopyable
320
+ {
321
+ mutable io_service m_ios;
322
+ static mutex m_mutex;
323
+ platform_stream m_socket;
324
+
325
+ shared_ptr<winEventComm> m_comm;
326
+ shared_ptr<exitCheckHnadler> m_exitHandler;
327
+ shared_ptr<sharedMem> m_sharedMem;
328
+ shared_ptr<IAppModule> m_module;
329
+ size_t m_readLen;
330
+
331
+ void run()
332
+ {
333
+ bool sentResult = true;
334
+ while (sentResult)
335
+ {
336
+ if (m_comm->recv(3000, m_exitHandler.get())==false)
337
+ return;
338
+ bool complete = false;
339
+ m_readLen = *((unsigned int*)m_sharedMem->readBuffer());
340
+ if (m_readLen==0)
341
+ return;
342
+ m_module->onRead(m_sharedMem->readBuffer(), m_readLen, complete);
343
+ if (complete)
344
+ {
345
+ size_t size=0;
346
+ if (m_module->execute(m_sharedMem->writeBuffer(), size, NULL) == EXECUTE_RESULT_QUIT)
347
+ return ;
348
+ else
349
+ m_readLen = 0;
350
+
351
+ sentResult = m_comm->send();
352
+ m_module->cleanup();
353
+ }
354
+ }
355
+ }
356
+
357
+ char* getUniqName(DWORD id,__int64 clientid, const char* name, char* buf, int size)
358
+ {
359
+ sprintf_s(buf, size, "%s_%lu_%Lu", name, id, clientid);
360
+ return buf;
361
+ }
362
+
363
+ public:
364
+ static std::string m_pipeName;
365
+ static unsigned int m_shareMemSize;
366
+ connection(): m_socket(m_ios),m_readLen(0)
367
+ {
368
+ mutex::scoped_lock lck(m_mutex);
369
+ connections.push_back(this);
370
+ ++g_connections;
371
+ }
372
+
373
+ ~connection()
374
+ {
375
+ if (connections.size())
376
+ {
377
+ mutex::scoped_lock lck(m_mutex);
378
+ std::vector<connection*>::iterator it = find(connections.begin(), connections.end(), this);
379
+ if (it != connections.end())
380
+ {
381
+ connections.erase( it);
382
+ --g_connections;
383
+ }
384
+ }
385
+ m_exitHandler.reset();
386
+ }
387
+
388
+ void close()
389
+ {
390
+ m_comm->chancel();
391
+ }
392
+
393
+ io_service& ios()const{return m_ios;};
394
+
395
+ platform_stream& socket(){return m_socket;}
396
+
397
+ void setModule(shared_ptr<IAppModule> p)
398
+ {
399
+ m_module = p;
400
+ if (m_exitHandler)
401
+ m_exitHandler->setModule(p.get());
402
+ }
403
+
404
+ void start()
405
+ {
406
+ m_ios.reset();
407
+
408
+ char buf[128];
409
+ char buf2[50];
410
+ char tmp[50];
411
+ char tmp2[50];
412
+ system::error_code e;
413
+ std::size_t len = asio::read(m_socket, buffer(buf, 16), e);
414
+ if (len!=16)
415
+ THROW_BZS_ERROR_WITH_MSG("readThredID error");
416
+
417
+ DWORD clinetThreadID= *((DWORD*)(buf+4));
418
+ __int64 clientid = *((__int64*)(buf+8));
419
+ sprintf_s(tmp, 50, "Global\\%s", m_pipeName.c_str());
420
+ m_sharedMem.reset(new sharedMem(getUniqName(clinetThreadID, clientid, tmp , buf, 128), m_shareMemSize));
421
+ sprintf_s(tmp, 50, "Global\\%sToSrv", m_pipeName.c_str());
422
+ sprintf_s(tmp2, 50, "Global\\%sToClnt", m_pipeName.c_str());
423
+ m_comm.reset(new winEventComm(getUniqName(clinetThreadID, clientid, tmp, buf, 128)
424
+ , getUniqName(clinetThreadID, clientid, tmp2, buf2, 50)));
425
+ m_exitHandler.reset(new exitCheckHnadler(clinetThreadID));
426
+ if (m_module)
427
+ m_exitHandler->setModule(m_module.get());
428
+ m_module->onAccept(tmp, 50);
429
+
430
+ strcpy(tmp, "OK");
431
+ memcpy(tmp+3, &m_shareMemSize, 4);
432
+ asio::write(m_socket, buffer(tmp, 7), e);
433
+ run();
434
+
435
+ }
436
+
437
+ void cancel()
438
+ {
439
+ if (m_exitHandler)
440
+ m_exitHandler->setCancel(true);
441
+ ios().stop();
442
+ socket().cancel();
443
+ }
444
+
445
+ static std::vector<connection* > connections;
446
+
447
+ static void stop()
448
+ {
449
+ mutex::scoped_lock lck(m_mutex);
450
+ try
451
+ {
452
+ for (size_t i=0;i<connections.size();i++)
453
+ connections[i]->cancel();
454
+ }
455
+ catch(system::system_error &){};
456
+ }
457
+
458
+ };
459
+
460
+ std::vector<connection* > connection::connections;
461
+ mutex connection::m_mutex;
462
+ std::string connection::m_pipeName;
463
+ unsigned int connection::m_shareMemSize;
464
+
465
+ // ---------------------------------------------------------------------------
466
+ // worker
467
+ // ---------------------------------------------------------------------------
468
+
469
+ class worker : private noncopyable
470
+ {
471
+
472
+ static mutex m_mutex;
473
+ static std::vector< shared_ptr<thread> > m_threads;
474
+ static std::vector<worker*> m_workers; //used by Muliti thread.
475
+ static worker* worker::findWaitThread()
476
+ {
477
+ mutex::scoped_lock lck(m_mutex);
478
+ for (size_t i=0;i<m_workers.size();i++)
479
+ if (m_workers[i]->m_connection==NULL)
480
+ return m_workers[i];
481
+ return NULL;
482
+ }
483
+
484
+ shared_ptr<connection> m_connection;
485
+
486
+ bool resume(){return shutdown || m_connection;}
487
+
488
+ ~worker()
489
+ {
490
+ mutex::scoped_lock lck(m_mutex);
491
+ m_workers.erase( find(m_workers.begin(), m_workers.end(), this));
492
+ }
493
+
494
+ public:
495
+ static bool shutdown;
496
+ static const char* hostCheckName;
497
+ static boost::condition_variable condition;
498
+ static void worker::registThread(shared_ptr<thread> t)
499
+ {
500
+ mutex::scoped_lock lck(m_mutex);
501
+ m_threads.push_back(t);
502
+ }
503
+
504
+ static void worker::join()
505
+ {
506
+ for (size_t i=0;i<m_threads.size();i++)
507
+ m_threads[i]->join();
508
+ m_threads.erase(m_threads.begin(), m_threads.end());
509
+ }
510
+
511
+ /** In search of an empty worker thread,
512
+ * if there is nothing, it will create, perform and return.
513
+ */
514
+ static worker* worker::get(const IAppModuleBuilder* app)
515
+ {
516
+
517
+ worker* p = findWaitThread();
518
+ if (p==NULL)
519
+ {
520
+ thread::attributes attr;
521
+ attr.set_stack_size( 125 * 1024);
522
+ p = new worker();
523
+ shared_ptr<thread> t(new thread(attr, bind(&worker::run, p, app)));
524
+ registThread(t);
525
+ }
526
+ return p;
527
+ }
528
+
529
+ /**
530
+ * Call from accepter thread.
531
+ */
532
+ worker()
533
+ {
534
+ mutex::scoped_lock lck(m_mutex);
535
+ m_workers.push_back(this);
536
+ }
537
+
538
+ void worker::setConnection(shared_ptr<connection> conn)
539
+ {
540
+ m_connection = conn;
541
+ }
542
+
543
+ void run(const IAppModuleBuilder* app)
544
+ {
545
+ try
546
+ {
547
+ while (!shutdown)
548
+ {
549
+ if (m_connection)
550
+ {
551
+ system::error_code ec;
552
+ tcp::endpoint endpoint;
553
+ endpoint.address(address(address_v4::from_string("127.0.0.1")));
554
+ shared_ptr<IAppModule> mod(((IAppModuleBuilder*)app)->createSessionModule(endpoint, m_connection.get(), SERVER_TYPE_CPT));
555
+ m_connection->setModule(mod);
556
+ if (mod->checkHost(hostCheckName))
557
+ m_connection->start(); //It does not return, unless a connection is close.
558
+ m_connection.reset();
559
+ }
560
+
561
+ //TODO A used thread -- it is all held.
562
+ //The number of maintenance is decided and it is made not to hold any more.
563
+ mutex::scoped_lock lck(m_mutex);
564
+ ++g_waitThread;
565
+ condition.wait(lck, bind(&worker::resume, this));
566
+ --g_waitThread;
567
+
568
+ }
569
+ }
570
+ catch(bzs::rtl::exception &e)
571
+ {
572
+ if (server::erh)
573
+ {
574
+ if(const std::string *msg = getMsg(e))
575
+ {
576
+ std::string s = "Pipe server " + *msg;
577
+ server::erh->printError(s.c_str());
578
+ }else
579
+ server::erh->printError(boost::diagnostic_information(e).c_str());
580
+ }
581
+ }
582
+
583
+ catch(...)
584
+ {
585
+ if (server::erh)
586
+ server::erh->printError("pipe server Unknown");
587
+ }
588
+ //An end of this thread will delete self.
589
+ delete this;
590
+ }
591
+
592
+ };
593
+ bool worker::shutdown = false;
594
+ const char* worker::hostCheckName;
595
+ condition_variable worker::condition;
596
+ mutex worker::m_mutex;
597
+ std::vector< shared_ptr<thread> > worker::m_threads;
598
+ std::vector<worker*> worker::m_workers;
599
+
600
+
601
+ // ---------------------------------------------------------------------------
602
+ // server
603
+ // ---------------------------------------------------------------------------
604
+ inotifyHandler* server::erh=NULL;
605
+
606
+ /** server
607
+ * If it starts, a server will create the exclusive thread for accpter
608
+ * and will go into an infinite loop.
609
+ */
610
+ server::server(shared_ptr<IAppModuleBuilder> app, const std::string& name
611
+ , std::size_t max_connections, unsigned int shareMemSize,const char* hostCheckName)
612
+ : m_app(app), m_maxConnections(max_connections),m_stopped(false)
613
+
614
+ {
615
+ worker::hostCheckName = hostCheckName;
616
+ m_newConnection.reset(new connection());
617
+ connection::m_pipeName = name;
618
+ connection::m_shareMemSize = shareMemSize;
619
+ m_acceptor.open(name);
620
+ }
621
+
622
+ /** Start the server
623
+ */
624
+ void server::start()
625
+ {
626
+ shared_ptr<thread> t(new thread(bind(&server::run, this)));
627
+ worker::registThread(t);
628
+
629
+ }
630
+
631
+ void server::run()
632
+ {
633
+ try
634
+ {
635
+ if (erh)
636
+ erh->printInfo("Start Pipe server.");
637
+ while (1)
638
+ {
639
+ if (m_stopped) return;
640
+ while (connection::connections.size()>m_maxConnections)
641
+ {
642
+ Sleep(100);
643
+ if (m_stopped)
644
+ return;
645
+ }
646
+ //Time to await slight time and no pipe be exists.
647
+ //A client is trying connection several times.
648
+ m_acceptor.accept(m_newConnection->socket());
649
+ if (m_stopped) return;
650
+ system::error_code e;
651
+ onAccept(e);
652
+ }
653
+ }
654
+ catch(bzs::rtl::exception &e)
655
+ {
656
+ if (erh)
657
+ {
658
+ if(const std::string *msg = getMsg(e))
659
+ {
660
+ std::string s = "Pipe server accept " + *msg;
661
+ erh->printError(s.c_str());
662
+ }else
663
+ erh->printError(boost::diagnostic_information(e).c_str());
664
+ }
665
+ stop();
666
+ }
667
+ }
668
+
669
+ void server::onAccept(const system::error_code& e)
670
+ {
671
+ //connection is passed to a thread and it resumes.
672
+ if (!e)
673
+ {
674
+ worker* w = worker::get(m_app.get());
675
+ w->setConnection(m_newConnection);
676
+ worker::condition.notify_all();
677
+ m_newConnection.reset(new connection());
678
+ }
679
+ }
680
+
681
+ void server::doStop()
682
+ {
683
+ if (!m_stopped)
684
+ {
685
+ m_stopped = true;
686
+ if (erh)
687
+ erh->printInfo("Stopping Pipe server ...");
688
+ m_acceptor.cancel();
689
+ worker::shutdown = true;
690
+ connection::stop();
691
+ worker::condition.notify_all();
692
+ }
693
+ }
694
+
695
+ void server::stop()
696
+ {
697
+ doStop();
698
+ worker::join();
699
+ }
700
+
701
+ }//namespace pipe
702
+ }//namespace server
703
+ }//namespace netsvc
704
+ }//namespace bzs
705
+