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 | ... | ... |