In GUI systems the GUI maintenance and interaction are usually single-threaded.
As a consequence
calls to interact with GUI objects must be executed on that GUI thread,
otherwise undefined
behaviour may occur (usually hanging the GUI and its applications).
GUI systems usually supply a utility method that allows one to be called on the
GUI thread later.
As students are using the JavaFX GUI system (very easy to create complex GUIs
with SceneBuilder) it
has been interesting to observe the difficulties they (and "normal" users as
well!) face when trying
to correctly interface with the GUI on the GUI thread.
In order to come up with a solution that eases correct addressing of GUI
objects for Rexx
programmers, I came up with a utility class that will dispatch Rexx messages
when being executed on
the GUI thread.
While creating a tutorial application (one that uses a progress bar and various
labels to give
feedback to the user) everything has been working out fine, initially. Running
a demo application,
that constantly updates the GUI objects (without hanging the GUI! :) ) in
sub-second intervals (to
animate the progress bar and the datetime displayed in the labels) will run
successfully and
animates the progress bar and updates the labels accordingly. The principles
deployed are:
* a Rexx program uses JavaFX to load and create a GUI from a fxml-file, which
includes two Rexx
programs that get invoked one after the other by the Java FXMLLoader class
correctly,
* the GUI is created and displayed (GUI objects are configured by the Rexx
controller program
(which requires a Rexx package containing the Worker class that carries out
thw work),
* when pressing the start button a class method in the worker class gets
invoked on the GUI thread
and issues a "reply" to continue its work on a new (non-GUI) thread and it
invokes an unguarded
class method that issues a "reply" itself and which updates the GUI; the
progress of the work
between the Rexx class methods is communicated via class attributes, the
GUI-updating Rexx
method uses the JavaFX runLater-Utility method to have the updating Rexx
messages be carried out
on the GUI thread later
This works. :)
Here, there are at least two Rexx threads running concurrently (the Rexx worker
method and the Rexx
GUI updating method both employ "reply" and execute for the duration of the
worker method) plus the
JavaFX-GUI-thread which dispatches the Rexx messages coming from the Rexx GUI
updating method.
Then, between three and 30 seconds in running the demo application two
different things may happen:
a crash "out of the blue" or the "stalling of the program".
It may be interesting to know that this demo application now is always able to
cause these fatal
errors to occur (if they occur, then always, when Rexx messages are originating
from the Java GUI
thread!). And it seems that there are only two different stack traces that play
a role here!
Therefore this demo application may be eligible to be used to debug the
problem, as the fatal errors
are reproducible!
I can create a zip-archive that contains this application with the minimal
needed BSF4ooRexx files
e.g. for 32-bit Windows (then one needs to make sure that a 32-bit Java is also
installed in
addition to a 64-bit Java). This should allow anyone who knows ooRexx inner
workings to start to
debug this problem that has been hunting us for months by now!
So really seeking for help for fixing this! If there is anything else I can do
to help debug this,
please advise!
---rony
P.S.: Here are the two different pieces of information, depending whether the
application was
started via Java or via Rexx:
* via Java, hs_error*log-file stack-trace:
C [rexx.dll+0xc6479] DeadObject::remove+0x29
C [rexx.dll+0xce90e] DeadObjectPool::findFit+0x6e
C [rexx.dll+0xce4cf] NormalSegmentSet::allocateObject+0xff
C [rexx.dll+0xdb053] MemoryObject::newObject+0x63
C [rexx.dll+0x23eb5] new_object+0x15
C [rexx.dll+0xb8661] NativeActivation::operator new+0x11
C [rexx.dll+0xe32e1] ActivityManager::newNativeActivation+0x41
C [rexx.dll+0xeb488] Activity::createNewActivationStack+0x28
C [rexx.dll+0xedcb5] Activity::nestAttach+0x25
C [rexx.dll+0x1430c8] InterpreterInstance::attachThread+0x58
C [rexx.dll+0x14317f] InterpreterInstance::attachThread+0x1f
C [rexx.dll+0x828e2] AttachThread+0x32
C [BSF4ooRexx.dll+0x8aa4]
* or via Rexx and then using Visual Studio, e.g.
o Call Stack
> rexx.dll!MethodDictionary::getMethod(RexxString *
methodName=0x7ed9a640) Line 69 C++
rexx.dll!RexxBehaviour::methodLookup(RexxString *
messageName=0x7ed9a640) Line 432 C++
rexx.dll!RexxObject::messageSend(RexxString *
msgname=0x7ed9a640, RexxObject * * arguments=0x1cd6f3b8, unsigned int count=1,
ProtectedObject & result={...}) Line 815 C++
rexx.dll!RexxObject::operator_integerDivide(RexxObject *
operand=0x7e038f88) Line 2627 C++
rexx.dll!RexxObject::callOperatorMethod(unsigned int
methodOffset=5, RexxObject * argument=0x7e038f88) Line 2955 C++
rexx.dll!RexxBinaryOperator::evaluate(RexxActivation *
context=0x7e038d70, ExpressionStack * stack=0x7e038e38) Line 186 C++
rexx.dll!RexxInstructionExpression::evaluateExpression(RexxActivation *
context=0x7e038d70, ExpressionStack * stack=0x7e038e38) Line 229 C++
rexx.dll!RexxInstructionReturn::execute(RexxActivation *
context=0x7e038d70, ExpressionStack * stack=0x7e038e38) Line 72 C++
rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7e034178,
RexxString * name=0x7ed97e38, RexxObject * * _arglist=0x7d8950f0, unsigned int
_argcount=0, RexxInstruction * start=0x00000000, ProtectedObject &
resultObj={...}) Line 620 C++
rexx.dll!RexxCode::run(Activity * activity=0x7e0153d0,
MethodClass * method=0x7ed9a7e8, RexxObject * receiver=0x7e034178, RexxString *
msgname=0x7ed97e38, RexxObject * * argPtr=0x7d8950f0, unsigned int argcount=0,
ProtectedObject & result={...}) Line 212 C++
rexx.dll!MethodClass::run(Activity * activity=0x7e0153d0,
RexxObject * receiver=0x7e034178, RexxString * msgname=0x7ed97e38, RexxObject *
* argPtr=0x7d8950f0, unsigned int count=0, ProtectedObject & result={...}) Line
170 C++
rexx.dll!RexxObject::messageSend(RexxString *
msgname=0x7ed97e38, RexxObject * * arguments=0x7d8950f0, unsigned int count=0,
ProtectedObject & result={...}) Line 839 C++
rexx.dll!ExpressionStack::send(RexxString * message=0x7ed97e38,
unsigned int count=0, ProtectedObject & result={...}) Line 80 C++
rexx.dll!RexxExpressionMessage::evaluate(RexxActivation *
context=0x7e038c38, ExpressionStack * stack=0x7e038d00) Line 191 C++
rexx.dll!RexxInstructionAssignment::execute(RexxActivation *
context=0x7e038c38, ExpressionStack * stack=0x7e038d00) Line 129 C++
rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7e034178,
RexxString * name=0x7ed93730, RexxObject * * _arglist=0x00000000, unsigned int
_argcount=0, RexxInstruction * start=0x00000000, ProtectedObject &
resultObj={...}) Line 620 C++
rexx.dll!RexxCode::run(Activity * activity=0x7e0153d0,
MethodClass * method=0x7ed9a4c0, RexxObject * receiver=0x7e034178, RexxString *
msgname=0x7ed93730, RexxObject * * argPtr=0x00000000, unsigned int argcount=0,
ProtectedObject & result={...}) Line 212 C++
rexx.dll!MethodClass::run(Activity * activity=0x7e0153d0,
RexxObject * receiver=0x7e034178, RexxString * msgname=0x7ed93730, RexxObject *
* argPtr=0x00000000, unsigned int count=0, ProtectedObject & result={...}) Line
170 C++
rexx.dll!RexxObject::messageSend(RexxString *
msgname=0x7ed93730, RexxObject * * arguments=0x00000000, unsigned int count=0,
ProtectedObject & result={...}) Line 839 C++
rexx.dll!RexxObject::sendMessage(RexxString *
message=0x7ed93730, ProtectedObject & result={...}) Line 486 C++
rexx.dll!RexxInternalObject::requestString() Line 1201 C++
rexx.dll!RexxString::concatBlank(RexxObject *
otherObj=0x7e034178) Line 1293 C++
rexx.dll!RexxObject::callOperatorMethod(unsigned int
methodOffset=10, RexxObject * argument=0x7e034178) Line 2955 C++
rexx.dll!RexxBinaryOperator::evaluate(RexxActivation *
context=0x7e015298, ExpressionStack * stack=0x7e015360) Line 186 C++
rexx.dll!RexxInstruction::evaluateArguments(RexxActivation *
context=0x7e015298, ExpressionStack * stack=0x7e015360, RexxInternalObject * *
argArray=0x7df99f68, unsigned int argCount=4) Line 154 C++
rexx.dll!RexxInstructionMessage::execute(RexxActivation *
context=0x7e015298, ExpressionStack * stack=0x7e015360) Line 180 C++
rexx.dll!RexxActivation::run(RexxObject * _receiver=0x7df9bbc0,
RexxString * name=0x7df96c10, RexxObject * * _arglist=0x7d8950e4, unsigned int
_argcount=1, RexxInstruction * start=0x00000000, ProtectedObject &
resultObj={...}) Line 620 C++
rexx.dll!RexxActivation::dispatch() Line 441 C++
rexx.dll!Activity::runThread() Line 208 C++
rexx.dll!dispatch_activity_function(void *
arguments=0x7e0153d0) Line 65 C++
kernel32.dll!@BaseThreadInitThunk@12() Unknown
ntdll.dll!___RtlUserThreadStart@8() Unknown
ntdll.dll!__RtlUserThreadStart@8() Unknown
o Locals:
*- this 0x00000000 <NULL> MethodDictionary **
+ StringHashCollection <struct at NULL>
StringHashCollection
instanceMethods <Unable to read memory>
scopeList <Unable to read memory>
scopeOrders <Unable to read memory>
- methodName 0x7ed9a640 {hashValue=37 length=1
numberStringValue=0x00000000 <NULL> ...} RexxString *
- RexxObject {objectVariables=0x00000000 <NULL> }
RexxObject
+ RexxInternalObject {header={objectSize=40 flags=96
sizePadding=96 } behaviour=rexx.dll!0x62fad3d8 {classType=T_String (22) ...} }
RexxInternalObject
- objectVariables 0x00000000 <NULL>
VariableDictionary *
+ RexxInternalObject <struct at NULL>
RexxInternalObject
reservingActivity <Unable to read memory>
contents <Unable to read memory>
waitingActivities <Unable to read memory>
flags <Unable to read memory>
reserveCount <Unable to read memory>
nextDictionary <Unable to read memory>
scope <Unable to read memory>
hashValue 37 unsigned int
length 1 unsigned int
- numberStringValue 0x00000000 <NULL>
NumberString *
+ NumberStringBase <struct at NULL>
NumberStringBase
+ numberDigits 0x0000002c <Error reading characters of
string.> char[4]
- attributes {flags={_Array=0x7ed9a660 {18} } }
FlagSet<enum RexxString::StringFlag,32>
+ flags {_Array=0x7ed9a660 {18} } std::bitset<32>
- stringData 0x7ed9a664 "%" char[4]
[0] 37 '%' char
[1] 0 '\0' char
[2] 0 '\0' char
[3] 0 '\0' char
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Oorexx-devel mailing list
Oorexx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oorexx-devel