Josef Henryson wrote:
1. A component I need is implemented to be thread-safe and handle
sessions. This means that the component itself does not manage
threads but it saves session data locally with reference to the
current thread.
In essence, it appears to be written to require a thread/session binding.
Too bad, because separating threads from sessions would be a lot easier to
deal with, even in a C++ context.
2. I call this component which is a JNI-library (C++ & JNI files)
from my Java code, e.g. a web application. I want to be sure that
when I call the JNI library from the web application, the session
data stored in the library is always associated with the same user
thread. For example, the results from a second call should be based
on saved data from the first call.
That forced correlation to a thread is going to be a huge pain. To work
around it, you're going to have to use Threads to implement subroutines.
Besides being hideously ugly and prone to errors, this may adversely affect
latency, though it's probably the least of your concerns (correctness
trumps speed).
What you'll have to do is create a separate dedicated Thread whose sole
purpose is to make calls into the JNI library, and thereby retain the
required binding between a thread and a session. It should probably be a
Thread subclass, with one Java method for each action of interest to your
API. What each method has to do is:
1. store the method's args in instance fields.
2. notify the waiting Thread to take an action.
3. wait for the Thread to return.
4. collect return values from instance fields.
5. return from the method.
6. do all the above Thread-safely.
The dedicated Thread sits in a loop:
1. wait() indefinitely on an object.
2. awaken and decode an action-selector field.
3. pass other fields as args to native method.
4. store return values into fields.
5. notify() the other Thread that's waiting for results.
6. do all the above Thread-safely.
This is basically a grotesquely deformed producer-consumer queue of zero
length. It gets even uglier if there are lots of methods and you have a
giant switch statement to decode the action-selector. I'm feeling ill just
thinking about coding it.
The people developing the component tells me this is the way sessions
should be handled and that the Thread calling the library is linked
to the session data. They are C++ developers however and I'm not
convinced that this will work with Java in the same way as with C++.
There is no "should" here. They made a design choice. It may have been
intentional or unwitting, but it was still a choice. It may have been a
convenient choice for certain C++ situations, but I can easily imagine a
C++ session that wasn't tied to a single thread, so it still seems like a
needlessly limiting design choice to me.
If there was just a session-ptr to a struct, or an arbitrary opaque ID, and
you were given the option of where to store it instead of requiring it to
be a thread-local variable, then that seems much more open-ended and
practical to me.
If I were you, I'd be looking for another library that didn't force me to
abuse threads as subroutine control-locus stacks.
-- GG