Commit 9d3a83d141d384a3cd8c69025d3885a0b2f9989c
1 parent
8666c391
Exists in
master
and in
5 other branches
Debuggando uso simultâneo de várias sessões pelo mesmo aplicativo.
Showing
5 changed files
with
112 additions
and
10 deletions
Show diff stats
src/classlib/local.cc
... | ... | @@ -240,6 +240,8 @@ |
240 | 240 | throw exception("Can't find symbol %s",call[f].name); |
241 | 241 | } |
242 | 242 | |
243 | + session::lock(); | |
244 | + | |
243 | 245 | // Get Session handle, setup base callbacks |
244 | 246 | set_log_handler(loghandler); |
245 | 247 | set_trace_handler(tracehandler); |
... | ... | @@ -247,19 +249,36 @@ |
247 | 249 | |
248 | 250 | set_display_charset(); |
249 | 251 | |
252 | + session::unlock(); | |
253 | + | |
250 | 254 | } |
251 | 255 | |
252 | 256 | virtual ~local() |
253 | 257 | { |
258 | + session::lock(); | |
259 | + | |
260 | + debug("%s(%p,%p)",__FUNCTION__,this,this->hSession); | |
261 | + if(is_connected()) { | |
262 | + disconnect(); | |
263 | + } | |
264 | + | |
265 | + debug("%s(%p,%p)",__FUNCTION__,this,this->hSession); | |
254 | 266 | try |
255 | 267 | { |
256 | 268 | static void (*session_free)(H3270 *h) = (void (*)(H3270 *)) get_symbol("lib3270_session_free"); |
257 | 269 | |
270 | + debug("%s(%p,%p)",__FUNCTION__,this,this->hSession); | |
271 | + | |
258 | 272 | if(session_free && this->hSession) |
259 | 273 | session_free(this->hSession); |
274 | + | |
275 | + this->hSession = 0; | |
276 | + | |
260 | 277 | } |
261 | 278 | catch(exception e) { } |
262 | 279 | |
280 | + session::unlock(); | |
281 | + | |
263 | 282 | } |
264 | 283 | |
265 | 284 | bool is_connected(void) |
... | ... | @@ -282,7 +301,11 @@ |
282 | 301 | |
283 | 302 | int connect(void) |
284 | 303 | { |
285 | - return _connect(hSession,0); | |
304 | + session::lock(); | |
305 | + int rc = _connect(hSession,0); | |
306 | + session::unlock(); | |
307 | + | |
308 | + return rc; | |
286 | 309 | } |
287 | 310 | |
288 | 311 | int set_url(const char *uri) |
... | ... | @@ -292,7 +315,11 @@ |
292 | 315 | |
293 | 316 | int disconnect(void) |
294 | 317 | { |
295 | - return _disconnect(hSession); | |
318 | + session::lock(); | |
319 | + int rc = _disconnect(hSession); | |
320 | + session::unlock(); | |
321 | + | |
322 | + return rc; | |
296 | 323 | } |
297 | 324 | |
298 | 325 | bool is_ready(void) | ... | ... |
src/classlib/session.cc
... | ... | @@ -43,7 +43,56 @@ |
43 | 43 | #endif // HAVE_SYSLOG |
44 | 44 | |
45 | 45 | #if __cplusplus < 201103L |
46 | + | |
46 | 47 | #define nullptr NULL |
48 | + | |
49 | + #ifdef _WIN32 | |
50 | + | |
51 | + #error Implementar | |
52 | + | |
53 | + #else | |
54 | + | |
55 | + class recursive_mutex { | |
56 | + private: | |
57 | + pthread_mutex_t mtx; | |
58 | + pthread_mutexattr_t mtxAttr; | |
59 | + | |
60 | + public: | |
61 | + recursive_mutex() { | |
62 | + | |
63 | + memset(&mtx,0,sizeof(mtx)); | |
64 | + memset(&mtxAttr,0,sizeof(mtxAttr)); | |
65 | + | |
66 | + pthread_mutexattr_init(&mtxAttr); | |
67 | + pthread_mutexattr_settype(&mtxAttr, PTHREAD_MUTEX_RECURSIVE); | |
68 | + pthread_mutex_init(&mtx, &mtxAttr); | |
69 | + }; | |
70 | + | |
71 | + ~recursive_mutex() { | |
72 | + pthread_mutex_destroy(&mtx); | |
73 | + }; | |
74 | + | |
75 | + void lock(void) { | |
76 | + pthread_mutex_lock(&mtx); | |
77 | + }; | |
78 | + | |
79 | + void unlock(void) { | |
80 | + pthread_mutex_unlock(&mtx); | |
81 | + }; | |
82 | + | |
83 | + bool try_lock(void) { | |
84 | + return pthread_mutex_trylock(&mtx) == 0; | |
85 | + }; | |
86 | + }; | |
87 | + | |
88 | + | |
89 | + | |
90 | + #endif // _WIN32 | |
91 | + | |
92 | +#else | |
93 | + | |
94 | + #include <recursive_mutex> | |
95 | + | |
47 | 96 | #endif // !c11 |
48 | 97 | |
49 | 98 | |
... | ... | @@ -94,6 +143,19 @@ |
94 | 143 | session * session::last = nullptr; |
95 | 144 | session * (*session::factory)(const char *name) = nullptr; |
96 | 145 | |
146 | + static recursive_mutex mtx; | |
147 | + | |
148 | + | |
149 | + void session::lock() | |
150 | + { | |
151 | + mtx.lock(); | |
152 | + } | |
153 | + | |
154 | + void session::unlock() | |
155 | + { | |
156 | + mtx.unlock(); | |
157 | + } | |
158 | + | |
97 | 159 | void session::init() |
98 | 160 | { |
99 | 161 | trace("Loading %s objects",PACKAGE_NAME); | ... | ... |
src/include/pw3270/class.h
... | ... | @@ -132,6 +132,9 @@ |
132 | 132 | static void init(); |
133 | 133 | static void deinit(); |
134 | 134 | |
135 | + static void lock(); | |
136 | + static void unlock(); | |
137 | + | |
135 | 138 | // Factory methods and settings |
136 | 139 | static session * start(const char *name = 0); |
137 | 140 | static session * create(const char *name = 0) throw (std::exception); | ... | ... |
src/java/main.cc
... | ... | @@ -76,10 +76,14 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_init__Ljava_lang_String_2(JNIEnv *en |
76 | 76 | |
77 | 77 | try { |
78 | 78 | |
79 | + session::lock(); | |
80 | + | |
79 | 81 | jlong handle = reinterpret_cast<jlong>(session::create(id)); |
80 | 82 | env->SetLongField(obj, getHandleField(env, obj), handle); |
81 | 83 | env->ReleaseStringUTFChars( j_id, id); |
82 | 84 | |
85 | + session::unlock(); | |
86 | + | |
83 | 87 | } catch(std::exception &e) { |
84 | 88 | |
85 | 89 | env->ReleaseStringUTFChars( j_id, id); |
... | ... | @@ -95,13 +99,23 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_deinit(JNIEnv *env, jobject obj) { |
95 | 99 | |
96 | 100 | try { |
97 | 101 | |
102 | + session::lock(); | |
103 | + | |
98 | 104 | session *s = getHandle(env,obj); |
99 | 105 | |
106 | + trace("********************* Destruindo objeto %p",s); | |
107 | + | |
100 | 108 | if(s) { |
109 | + trace("********************* Destruindo objeto %p",s); | |
101 | 110 | delete s; |
111 | + trace("********************* Destruindo objeto %p",s); | |
102 | 112 | } |
103 | 113 | |
114 | + trace("********************* Destruindo objeto %p",s); | |
104 | 115 | env->SetLongField(obj, getHandleField(env, obj), 0); |
116 | + trace("********************* Destruindo objeto %p",s); | |
117 | + | |
118 | + session::unlock(); | |
105 | 119 | |
106 | 120 | } catch(std::exception &e) { |
107 | 121 | ... | ... |
src/lib3270/session.c
... | ... | @@ -97,13 +97,13 @@ void lib3270_session_free(H3270 *h) |
97 | 97 | if(h == default_session) |
98 | 98 | default_session = NULL; |
99 | 99 | |
100 | - | |
101 | 100 | // Release hostname info |
102 | 101 | release_pointer(h->host.current); |
103 | 102 | release_pointer(h->host.full); |
104 | 103 | release_pointer(h->host.srvc); |
105 | 104 | release_pointer(h->host.qualified); |
106 | 105 | |
106 | + trace("Releasing session %p",h); | |
107 | 107 | lib3270_free(h); |
108 | 108 | |
109 | 109 | } |
... | ... | @@ -258,14 +258,10 @@ H3270 * lib3270_session_new(const char *model) |
258 | 258 | |
259 | 259 | trace("%s - configured=%s",__FUNCTION__,default_session ? "Yes" : "No"); |
260 | 260 | |
261 | - if(default_session) | |
262 | - { | |
263 | - // TODO (perry#5#): Allocate a new structure. | |
264 | - errno = EBUSY; | |
265 | - return lib3270_get_default_session_handle(); | |
266 | - } | |
261 | + hSession = lib3270_malloc(sizeof(H3270)); | |
267 | 262 | |
268 | - hSession = default_session = lib3270_malloc(sizeof(H3270)); | |
263 | + if(!default_session) | |
264 | + default_session = hSession; | |
269 | 265 | |
270 | 266 | lib3270_session_init(hSession, model, _( "bracket" ) ); |
271 | 267 | ... | ... |