Problem - Compiled Code Calling Interpreted Code with a GUI

Hi,

I have written a library that supports publish/subscribe messaging and has already converted it to ROOT compatible interfaces. The ROOT interpreted code calls the Subscribe() method in the library passing a function pointer(callback function) and waits.

Once a message is received, this function gets called by the library. I am using CINT’s G__CallFunc interface to achieve the above as pointed out by Axel in a previous discussion. root.cern.ch/phpBB2/viewtopic.php?t=5408

The Subscribe() method uses a pthread internally so the caller should wait till it returns.

Now I am trying to update a histogram using the data received via the subscription messages.

Everything works as expected when I use the following two lines to stop the interpreted code from exiting after calling Subscribe() method in the library.

int a;
cin>>a

But, this will simply freeze the user interface and the histogram on the canvas get erased if another windows comes in front.

I tried the following, only for the GUI and it works fine as shown by Ilka (root.cern.ch/phpBB2/viewtopic.php?t=5655)

while(some condition){
gSystem->Sleep(100);
gSystem->ProcessEvents();
}

However, this does not work when the GUI is integrated with the publish/subscribe library. It gives a segmentation violation error.

I even tried using a custom wait function which utilize “usleep()” of C++ but still it crashes when the callback function get called from the library.

This is how I call the callback function from the compiled code.

G__CallFunc func;
G__ClassInfo *cl=new C__ClassInfo(className);
Long_t offset;

char temp[128];
sprintf(temp,"(void **)%-p,(char *)%-p,(int)%d",this->tCallback->getArgs(),payload,payloadSize);

int error=0;

func.SetFunc(cl,funcName.c_str(),temp,&offset);
func.Exec(0);

======================

Could someone please help me to figure out a possible solution to this?

Thank you,
-Jaliya

The Subscribe() function takes a function pointer from the interpreted code and call that function when a message is received by the

Hi,

very difficult to tell without the code. Maybe you could start a debugger and check where and why it crashes? Also I don’t understand why you use cin and why you need “to stop the interpreted code from exiting after calling Subscribe() method in the library”. If you use G__CallFunc you don’t need any active interpreter call.

Cheers, Axel.

Hi Axel,

First of all, thank you very much for helping me to figure this out.

Let me add one more observation.

I am passing some object references created from the interpreted code to the library and then the library will pass them back to the callback function when it calls it. So the object references go through the following path;

Interpreted Code (Main Program) ->Library( Subscribe)->Interpreted Code(Callback function)

If I don’t need to access those references it works fine even without the cin or any other wait procedure.

But since I need to access those objects I have to keep the main program from exiting.

This is the my callback function:

void callback(void **v,char *bytes,int length);

This is how I call the library:

void (* f)(void **v,char *bytes,int length);
f=&callback;

TServiceClient tc; tc.Init(NB_BROKER_HOST,NB_BROKER_PORT,NB_ENTITY_ID,NB_TEMPLATE_ID);
TCallback tbk;
tbk.registerCallback(f,args);
tc.Subscribe(DEMO_TOPIC,&tbk);

==============================

Now the TServiceClient internally wait for data from a socket and call the function pointer (callback) passing the data and also the “args” passed in from the interpreted code.

Is it possible to pass arguments between interpreted code and the library as I am trying in my code. Please let me know.

Thanks,
-jaliya

Hi,

that should be possible, as long as the compiled code is not trying to access these objects, but just passes their addresses around. So you still have two options: use a debugger or post your complete code with instructions how to build it and how to reproduce the problem.

Cheers, Axel.

Hi Axel,

I am attaching the source code with a small sample that will re-create the problem that i am facing with.

All the source is in the attachment and the steps for building it and running the application are as follows;

copy the attachment to a directory
untar it
go to src directory and execute the followings
make gendict
make all

open two console tabs and in one go to the samples directory and run
root TestPubSub.C

on the other go to the bin directory and run
./pubsub 8909 /clarens/nb/demo/topic

Ok, now you will see it is working because I have put the cin>>in in the TestPubSub.C under HandleMessage() method. If I remove it it won’t work and produces the error.

Thank you very much for helping me to figure out this.

-jaliya
root_talk.tar.gz (112 KB)

Hi Axel,

I found the problem. :slight_smile:
Too bad that I was passing a local variable to the callback function. :frowning:

I am sorry if I waste your time. Thanks a lot for the help.

-Jaliya

Hi,

no problem. I just realized that I should probably point out that (the default) CINT is not thread safe; you cannot safely call interpreted functions from different threads. Instead, re-route the calls to one “interpreter” thread, e.g using messages.

Cheers, Axel.

Hi Axel,

Thanks for the information. Right now I have only one thread accessing the interpreted code so it will be ok, but could you please explain little bit more the method that you have suggested.

Thanks,
-jaliya

Hi,

CINT’s function should all be called within one thread, lets call it the interpreter thread. To allow several threads to access the interpreter they need to tell that interpreter thread what to call and they need to wait for the interpreter thread to call that requested function. This can e.g. be done by adding messages to the interpreter thread (which method to call, where to put the return value etc) to a collection that is read out by the interpreter thread. Each access of that collection would need to be locked of course.

Cheers, Axel.

Hi Axel,

Thank you very much for the explanation.

-jaliya