diff --git a/src/classlib/local.cc b/src/classlib/local.cc index 95c557c..bdeedd9 100644 --- a/src/classlib/local.cc +++ b/src/classlib/local.cc @@ -240,6 +240,8 @@ throw exception("Can't find symbol %s",call[f].name); } + session::lock(); + // Get Session handle, setup base callbacks set_log_handler(loghandler); set_trace_handler(tracehandler); @@ -247,19 +249,36 @@ set_display_charset(); + session::unlock(); + } virtual ~local() { + session::lock(); + + debug("%s(%p,%p)",__FUNCTION__,this,this->hSession); + if(is_connected()) { + disconnect(); + } + + debug("%s(%p,%p)",__FUNCTION__,this,this->hSession); try { static void (*session_free)(H3270 *h) = (void (*)(H3270 *)) get_symbol("lib3270_session_free"); + debug("%s(%p,%p)",__FUNCTION__,this,this->hSession); + if(session_free && this->hSession) session_free(this->hSession); + + this->hSession = 0; + } catch(exception e) { } + session::unlock(); + } bool is_connected(void) @@ -282,7 +301,11 @@ int connect(void) { - return _connect(hSession,0); + session::lock(); + int rc = _connect(hSession,0); + session::unlock(); + + return rc; } int set_url(const char *uri) @@ -292,7 +315,11 @@ int disconnect(void) { - return _disconnect(hSession); + session::lock(); + int rc = _disconnect(hSession); + session::unlock(); + + return rc; } bool is_ready(void) diff --git a/src/classlib/session.cc b/src/classlib/session.cc index dc8fc0d..4b02373 100644 --- a/src/classlib/session.cc +++ b/src/classlib/session.cc @@ -43,7 +43,56 @@ #endif // HAVE_SYSLOG #if __cplusplus < 201103L + #define nullptr NULL + + #ifdef _WIN32 + + #error Implementar + + #else + + class recursive_mutex { + private: + pthread_mutex_t mtx; + pthread_mutexattr_t mtxAttr; + + public: + recursive_mutex() { + + memset(&mtx,0,sizeof(mtx)); + memset(&mtxAttr,0,sizeof(mtxAttr)); + + pthread_mutexattr_init(&mtxAttr); + pthread_mutexattr_settype(&mtxAttr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mtx, &mtxAttr); + }; + + ~recursive_mutex() { + pthread_mutex_destroy(&mtx); + }; + + void lock(void) { + pthread_mutex_lock(&mtx); + }; + + void unlock(void) { + pthread_mutex_unlock(&mtx); + }; + + bool try_lock(void) { + return pthread_mutex_trylock(&mtx) == 0; + }; + }; + + + + #endif // _WIN32 + +#else + + #include + #endif // !c11 @@ -94,6 +143,19 @@ session * session::last = nullptr; session * (*session::factory)(const char *name) = nullptr; + static recursive_mutex mtx; + + + void session::lock() + { + mtx.lock(); + } + + void session::unlock() + { + mtx.unlock(); + } + void session::init() { trace("Loading %s objects",PACKAGE_NAME); diff --git a/src/include/pw3270/class.h b/src/include/pw3270/class.h index 2f62691..d5261a8 100644 --- a/src/include/pw3270/class.h +++ b/src/include/pw3270/class.h @@ -132,6 +132,9 @@ static void init(); static void deinit(); + static void lock(); + static void unlock(); + // Factory methods and settings static session * start(const char *name = 0); static session * create(const char *name = 0) throw (std::exception); diff --git a/src/java/main.cc b/src/java/main.cc index b3eaf2c..feccc6a 100644 --- a/src/java/main.cc +++ b/src/java/main.cc @@ -76,10 +76,14 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_init__Ljava_lang_String_2(JNIEnv *en try { + session::lock(); + jlong handle = reinterpret_cast(session::create(id)); env->SetLongField(obj, getHandleField(env, obj), handle); env->ReleaseStringUTFChars( j_id, id); + session::unlock(); + } catch(std::exception &e) { env->ReleaseStringUTFChars( j_id, id); @@ -95,13 +99,23 @@ JNIEXPORT jint JNICALL Java_pw3270_terminal_deinit(JNIEnv *env, jobject obj) { try { + session::lock(); + session *s = getHandle(env,obj); + trace("********************* Destruindo objeto %p",s); + if(s) { + trace("********************* Destruindo objeto %p",s); delete s; + trace("********************* Destruindo objeto %p",s); } + trace("********************* Destruindo objeto %p",s); env->SetLongField(obj, getHandleField(env, obj), 0); + trace("********************* Destruindo objeto %p",s); + + session::unlock(); } catch(std::exception &e) { diff --git a/src/lib3270/session.c b/src/lib3270/session.c index e7f7838..a1bcc76 100644 --- a/src/lib3270/session.c +++ b/src/lib3270/session.c @@ -97,13 +97,13 @@ void lib3270_session_free(H3270 *h) if(h == default_session) default_session = NULL; - // Release hostname info release_pointer(h->host.current); release_pointer(h->host.full); release_pointer(h->host.srvc); release_pointer(h->host.qualified); + trace("Releasing session %p",h); lib3270_free(h); } @@ -258,14 +258,10 @@ H3270 * lib3270_session_new(const char *model) trace("%s - configured=%s",__FUNCTION__,default_session ? "Yes" : "No"); - if(default_session) - { - // TODO (perry#5#): Allocate a new structure. - errno = EBUSY; - return lib3270_get_default_session_handle(); - } + hSession = lib3270_malloc(sizeof(H3270)); - hSession = default_session = lib3270_malloc(sizeof(H3270)); + if(!default_session) + default_session = hSession; lib3270_session_init(hSession, model, _( "bracket" ) ); -- libgit2 0.21.2