Commit 9d3a83d141d384a3cd8c69025d3885a0b2f9989c

Authored by Perry Werneck
1 parent 8666c391

Debuggando uso simultâneo de várias sessões pelo mesmo aplicativo.

src/classlib/local.cc
@@ -240,6 +240,8 @@ @@ -240,6 +240,8 @@
240 throw exception("Can't find symbol %s",call[f].name); 240 throw exception("Can't find symbol %s",call[f].name);
241 } 241 }
242 242
  243 + session::lock();
  244 +
243 // Get Session handle, setup base callbacks 245 // Get Session handle, setup base callbacks
244 set_log_handler(loghandler); 246 set_log_handler(loghandler);
245 set_trace_handler(tracehandler); 247 set_trace_handler(tracehandler);
@@ -247,19 +249,36 @@ @@ -247,19 +249,36 @@
247 249
248 set_display_charset(); 250 set_display_charset();
249 251
  252 + session::unlock();
  253 +
250 } 254 }
251 255
252 virtual ~local() 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 try 266 try
255 { 267 {
256 static void (*session_free)(H3270 *h) = (void (*)(H3270 *)) get_symbol("lib3270_session_free"); 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 if(session_free && this->hSession) 272 if(session_free && this->hSession)
259 session_free(this->hSession); 273 session_free(this->hSession);
  274 +
  275 + this->hSession = 0;
  276 +
260 } 277 }
261 catch(exception e) { } 278 catch(exception e) { }
262 279
  280 + session::unlock();
  281 +
263 } 282 }
264 283
265 bool is_connected(void) 284 bool is_connected(void)
@@ -282,7 +301,11 @@ @@ -282,7 +301,11 @@
282 301
283 int connect(void) 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 int set_url(const char *uri) 311 int set_url(const char *uri)
@@ -292,7 +315,11 @@ @@ -292,7 +315,11 @@
292 315
293 int disconnect(void) 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 bool is_ready(void) 325 bool is_ready(void)
src/classlib/session.cc
@@ -43,7 +43,56 @@ @@ -43,7 +43,56 @@
43 #endif // HAVE_SYSLOG 43 #endif // HAVE_SYSLOG
44 44
45 #if __cplusplus < 201103L 45 #if __cplusplus < 201103L
  46 +
46 #define nullptr NULL 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 #endif // !c11 96 #endif // !c11
48 97
49 98
@@ -94,6 +143,19 @@ @@ -94,6 +143,19 @@
94 session * session::last = nullptr; 143 session * session::last = nullptr;
95 session * (*session::factory)(const char *name) = nullptr; 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 void session::init() 159 void session::init()
98 { 160 {
99 trace("Loading %s objects",PACKAGE_NAME); 161 trace("Loading %s objects",PACKAGE_NAME);
src/include/pw3270/class.h
@@ -132,6 +132,9 @@ @@ -132,6 +132,9 @@
132 static void init(); 132 static void init();
133 static void deinit(); 133 static void deinit();
134 134
  135 + static void lock();
  136 + static void unlock();
  137 +
135 // Factory methods and settings 138 // Factory methods and settings
136 static session * start(const char *name = 0); 139 static session * start(const char *name = 0);
137 static session * create(const char *name = 0) throw (std::exception); 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,10 +76,14 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_init__Ljava_lang_String_2(JNIEnv *en
76 76
77 try { 77 try {
78 78
  79 + session::lock();
  80 +
79 jlong handle = reinterpret_cast<jlong>(session::create(id)); 81 jlong handle = reinterpret_cast<jlong>(session::create(id));
80 env->SetLongField(obj, getHandleField(env, obj), handle); 82 env->SetLongField(obj, getHandleField(env, obj), handle);
81 env->ReleaseStringUTFChars( j_id, id); 83 env->ReleaseStringUTFChars( j_id, id);
82 84
  85 + session::unlock();
  86 +
83 } catch(std::exception &e) { 87 } catch(std::exception &e) {
84 88
85 env->ReleaseStringUTFChars( j_id, id); 89 env->ReleaseStringUTFChars( j_id, id);
@@ -95,13 +99,23 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_deinit(JNIEnv *env, jobject obj) { @@ -95,13 +99,23 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_deinit(JNIEnv *env, jobject obj) {
95 99
96 try { 100 try {
97 101
  102 + session::lock();
  103 +
98 session *s = getHandle(env,obj); 104 session *s = getHandle(env,obj);
99 105
  106 + trace("********************* Destruindo objeto %p",s);
  107 +
100 if(s) { 108 if(s) {
  109 + trace("********************* Destruindo objeto %p",s);
101 delete s; 110 delete s;
  111 + trace("********************* Destruindo objeto %p",s);
102 } 112 }
103 113
  114 + trace("********************* Destruindo objeto %p",s);
104 env->SetLongField(obj, getHandleField(env, obj), 0); 115 env->SetLongField(obj, getHandleField(env, obj), 0);
  116 + trace("********************* Destruindo objeto %p",s);
  117 +
  118 + session::unlock();
105 119
106 } catch(std::exception &e) { 120 } catch(std::exception &e) {
107 121
src/lib3270/session.c
@@ -97,13 +97,13 @@ void lib3270_session_free(H3270 *h) @@ -97,13 +97,13 @@ void lib3270_session_free(H3270 *h)
97 if(h == default_session) 97 if(h == default_session)
98 default_session = NULL; 98 default_session = NULL;
99 99
100 -  
101 // Release hostname info 100 // Release hostname info
102 release_pointer(h->host.current); 101 release_pointer(h->host.current);
103 release_pointer(h->host.full); 102 release_pointer(h->host.full);
104 release_pointer(h->host.srvc); 103 release_pointer(h->host.srvc);
105 release_pointer(h->host.qualified); 104 release_pointer(h->host.qualified);
106 105
  106 + trace("Releasing session %p",h);
107 lib3270_free(h); 107 lib3270_free(h);
108 108
109 } 109 }
@@ -258,14 +258,10 @@ H3270 * lib3270_session_new(const char *model) @@ -258,14 +258,10 @@ H3270 * lib3270_session_new(const char *model)
258 258
259 trace("%s - configured=%s",__FUNCTION__,default_session ? "Yes" : "No"); 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 lib3270_session_init(hSession, model, _( "bracket" ) ); 266 lib3270_session_init(hSession, model, _( "bracket" ) );
271 267