How to dlclose and unmap DSO even when tls_dtors exist, or reinitialize DSO when calling dlopen at second round - dlopen

I want to get fresh DSO (which means it's global variable is set to init status) whenever I call dlopen. But when DSO contains tls dtor, dlclose will not unload/unmap this DSO, and at next time I dlopen it, it gives me old handler and old DSO status.
So how to dlclose and unmap DSO even when tls_dtors exist, or reinitialize DSO when calling dlopen at second round

Related

How to use an external variable in linkage section in COBOL and pass values from it into a new module and write into my new output file

Could someone please tell me why a variable is declared as "External" in a module and how to use that in other modules through Linkage section and how to pass them into new fields so I can write it to a new file.
EXTERNAL items are commonly found in WORKING-STORAGE. These are normally not passed from one program to another via CALL and LINKAGE but shared directly via the COBOL runtime.
Declaring an item as EXTERNAL behaves like "runtime named global storage", you assign a name and a length to a global piece of memory and can access it anywhere in the same runtime unit (no direct CALL needed), even in cases like the following:
MAIN
-> CALL B
B: somevar EXTERNAL
-> MOVE 'TEST' TO somevar
-> CANCEL B
-> CALL C
C: somevar EXTERNAL -> now contains 'TEST'
On an IBM Z mainframe, running z/OS, the runtime routines for all High Level Languages (HLLs) is called Language Environment (LE). Decades ago, each HLL had its own runtime and this caused some problems when they were mixed into the same run unit; starting in the early 1990s IBM switched all HLLs to LE for their runtime.
LE has the concept of an enclave. Part of the text at that link says an enclave is the equivalent of a run unit in COBOL.
Your question is tagged CICS, and sometimes behavior is different when running in that environment. Quoting from that link...
Under CICS the execution of a CICS LINK command creates what Language Environment calls a Child Enclave. A new environment is initialized and the child enclave gets its runtime options. These runtime options are independent of those options that existed in the creating enclave.
[...]
Something similar happens when a CICS XCTL command is executed. In this case we do not get a child enclave, but the existing enclave is terminated and then reinitialized with the runtime options determined for the new program. The same performance considerations apply.
So, as #SimonSobich noted, if you use CALLs to invoke your subroutines when running in CICS, EXTERNAL data is global to the run unit. But, if you use EXEC CICS XCTL to invoke your subroutines, you may see different behavior and have to design your application differently.

TCL Destructor is not called on window close

I have a class DataDialog, which contains a destructor like
destructor {
puts "DataDialog has been destructed"
#further code
}
If I close the application via the X-window-button this destructor is not called. If I close it over file->close it is called.
On the toplevel I have the following
wm protocol . WM_DELETE_WINDOW {
Exit 0
}
How can I change this behaviour to call all destructors (or at least the one of my class DataDialog)?
How about
wm protocol . WM_DELETE_WINDOW {
DataDialog destroy
Exit 0
}
If you call exit (or if you delete the interpreter) then Tcl does not guarantee to call destructors. That's because tearing down everything in memory can be surprisingly expensive. Critical resources typically have extra exit handlers registered at the C level to ensure that they get cleaned up correctly, but they're very much the exception; the only ones you likely use on a common basis are channels (which are flushed on exit). There isn't any Tcl-level for doing this; those handlers are usually called at points where it is no longer safe to call Tcl commands.
However, the default behaviour for handling cooperative window closure is effectively to send a <Destroy> message to the window. Those aren't entirely interceptable (the window will go away) but you can bind to them to find out when they occur. Be aware of one quirk though: toplevel windows also listen to all the events of their children (though they don't get killed by passing <Destroy>s unless they're sent to them directly). Check that %W actually refers to the window that you think you're really listening to before taking special action.

Aapche-Camel save error information on each retry

I have an Apache Camel route which handles messages from a queue. To better understand what is happening at runtime I also keep the execution state in a database (number of retries, last execution state,...). I would like to use the redelivery mechanism from the exception handler but which performs some processing on every failure to update my database record.
from("jms:myinputqueue")
.onException(RetriableException.class)
.maximumRedeliveries(5)
.maximumRedeliveryDelay(10000)
.useOriginalMessage()
.to("log:store error information in database about each attempt") // (1)
.end() // onException
.to("log:apply business logic here which can throw exceptions")
;
The part (1) is only executed after all retries are exhausted, so only once.
I've read Apache Camel- Message Redelivery happens before onexception block executes but the suggested solution ''onRedelivery'' is executed before the beginning of a new retry. I need to store the result on each failure so I can save the last state (error message) in the database.
Any suggestions ?
There is an onExceptionOccurred processor you can use that is called when the exception happened.
Its included in Camel 2.17 onwards: https://issues.apache.org/jira/browse/CAMEL-9069

How can i detect that a thread not created by me is finished ? (to call mysql_thread_end)

I have a problem with the design of mysql client library.
MySQL requires that each thread that uses the MySQL API first call mysql_thread_init()
and at the end call
mysql_thread_end().
If the thread fails to call
mysql_thread_end(),
then MySQL will block the main thread at program termination and wait for this threads to call
mysql_thread_end().
If that doesn't happen, then it prints an error message to STDERR. Not a very user-friendly behavior.
now the problem is that i m inside an ISAPI dll, it's not me who create the thread (nor destructing it), it's IIS that manage it.
How can i be warned then the thread will end to call mysql_thread_end ?

Exceptions in Lablgtk callbacks

In Lablgtk, whenever there is an exception in a callback, the exception is automatically caught and an error message is printed in the console, such as:
(prog:12345) LablGTK-CRITICAL **: gtk_tree_model_foreach_func:
callback raised an exception
This gives no stack trace and no details about the exception, and because it is caught I cannot retrieve this information myself.
Can I enable more detailed logging information for this case? Or prevent the exception from being caught automatically?
I guess the best way to do so is to catch your exception manually and handle it yourself.
let callback_print_exn f () =
try f () with
e -> my_exn_printer e
Assuming val my_exn_printer : exn -> unit is your custom exception printer, you can simply print your callbacks exceptions by replacing ~callback:f by ~callback:(callback_print_exn f) in your code.
Of course, you can also with that method send that exception to another
thread, register a "callback id" that would be passed along with your exception...
About the stack trace, I'm not sure you can retrieve it easily. As it's launched as a callback, you probably want to know the signal used and that can be stored in your callback handler.
I had another similar issue, but this time it was harder to find where to put the calls to intercept the exception.
Fortunately, this time there was a very specific error message coming from the Glib C code:
GLib-CRITICAL **: Source ID ... was not found when attempting to remove it`
Stack Overflow + grep led me to the actual C function, but I could not find which of the several Lablgtk functions bound to this code was the culprit.
So I downloaded the Glib source, added an explicit segmentation fault to the code, compiled it and used LD_LIBRARY_PATH to force my modified Glib version to be loaded.
Then I ran the OCaml binary with gdb, and I got my stack trace, with the precise line number where the Lablgtk function was being called. And from there it was a quick 3-line patch.
Hacks like this one (which was still faster than trying to find where to intercept the call) could be avoided by having a "strict mode" preventing exceptions from being automatically caught. I still believe such a switch should be available for Lablgtk users, and hope it will eventually be available.