Re: ORBit2.8.3 thread problem



Hi,

It's not working.
Attached file is the new version I used.   I only replace the global
variables by local instance.

In fact, I found the key problem is whether the Echo_echoString()
had been called from main thread or not.  If main thread and
child thread both call Echo_echoString(), then the child thread will
always stop at 8192th ????

If I use one, two or even three child threads without calling CORBA
method from main thread, then the 8192 limit will not show up ?

For the echo-client-t.c from ORBit-2.8.2 (Fedora Core 1), if I add
"echo_client_thread(NULL);" before g_thread_join() ... means that
I call CORBA method from main thread ... I found that the echo-client-t
also hangup at some point.

I also attached the modified version of echo-client-t.c

Thanks
Kuang-Chun Cheng
kccheng openate com



Nickolay V. Shmyrev wrote:

Well, now your problems is easily reproduced and can be solved. The main
idea is that you should be carefully, when you share memory (global
variables) between threads. You have two global variables - global_orb
and echo_client. Global orb is nicely shared because you create it with
"orb-local-mt". It is done in ORBit library. But nobody will manage
locking of echo_client structure. You should do it yourself. I mean that
to solve your problem you should either create echo_client instance in
each thread (then you can share only IOR string, which is constant) or
lock it with mutex during usage of Echo_echoString. I prefer first
solution.

You can look at echo-client-t.c example in ORBit-2.10/test directory, to
see proper example.

Your functions should look like:

void *thread_echo(void *arg)
{
	char buf[1024];
	int i = 0;
	double tmp;
	Echo echo_service = CORBA_OBJECT_NIL;

	echo_service = CORBA_ORB_string_to_object (global_orb, echo_ior, ev);

	for (i=0; i<10000; ++i) {
		printf("Thread %d\n", i);
		snprintf(buf, 1024, "Thread %d\n", i++);
		Echo_echoString(echo_service, buf, &tmp, ev);
	}

	CORBA_Object_release (echo_service, ev);
	return NULL;
}

static void
client_run (CORBA_Environment        *ev)
{
	char buf[1024];
	int i = 0;
	double tmp;
	pthread_t thread;
       Echo echo_service = CORBA_OBJECT_NIL;

	pthread_create(&thread, NULL, thread_echo, NULL);

	echo_service = CORBA_ORB_string_to_object (global_orb, echo_ior, ev);

	for (i=0; i<10000; ++i) {
		printf("Hello %d\n", i);
		snprintf(buf, 1024, "Hello %d\n", i++);

		Echo_echoString(echo_service, buf, &tmp, ev);
	}

	CORBA_Object_release (echo_service, ev);
	printf("Hit any key to quit\n");
	getchar();
}

							Shmyrev.
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <orbit/orbit.h>
#include <linc/linc.h>

#include "echo.h"


static CORBA_ORB  global_orb = CORBA_OBJECT_NIL; /* global orb */
 
static void
client_shutdown (int sig)
{
        CORBA_Environment  local_ev[1];
        CORBA_exception_init(local_ev);
 
        if (global_orb != CORBA_OBJECT_NIL)
        {
                CORBA_ORB_shutdown (global_orb, FALSE, local_ev);
                etk_abort_if_exception (local_ev, "caught exception");
        }
}
        
static void
client_init (int               *argc_ptr,
	     char              *argv[],
             CORBA_ORB         *orb,
             CORBA_Environment *ev)
{
        /* init signal handling */
 
        signal(SIGINT,   client_shutdown);
        signal(SIGQUIT,  client_shutdown);
        signal(SIGTERM,  client_shutdown);
         
        /* create Object Request Broker (ORB) */
         
        (*orb) = CORBA_ORB_init(argc_ptr, argv, "orbit-local-mt-orb", ev);
        if (etk_raised_exception(ev)) return;
}

static void
client_cleanup (CORBA_ORB                 orb,
                CORBA_Object              service,
                CORBA_Environment        *ev)
{
        /* releasing managed object */
        CORBA_Object_release(service, ev);
        if (etk_raised_exception(ev)) return;
 
        /* tear down the ORB */
        if (orb != CORBA_OBJECT_NIL)
        {
                /* going to destroy orb.. */
                CORBA_ORB_destroy(orb, ev);
                if (etk_raised_exception(ev)) return;
        }
}

void *thread_echo(void *arg)
{
	char buf[1024];
	int i = 0;
	CORBA_char filename[] = "echo.ref";
	Echo echo_service = CORBA_OBJECT_NIL;
	CORBA_Environment ev[1];

	echo_service = (Echo) etk_import_object_from_file (global_orb,
							   filename,
							   &ev);
	for (i=0; i<20000; ++i) {
		printf("Thread %d\n", i);
		snprintf(buf, 1024, "Thread %d\n", i++);
		Echo_echoString(echo_service, buf, ev);
		if (etk_raised_exception (ev)) return;
	}
	return NULL;
}

static void
client_run (Echo  echo_service,
	    CORBA_Environment        *ev)
{
	char buf[1024];
	int i = 0;
	pthread_t thread;

	pthread_create(&thread, NULL, thread_echo, NULL);
	pthread_create(&thread, NULL, thread_echo, NULL);
/*
	for (i=0; i<20000; ++i) {
		printf("Hello %d\n", i);
		snprintf(buf, 1024, "Hello %d\n", i++);

		Echo_echoString(echo_service, buf, ev);
		if (etk_raised_exception (ev)) return;
	}
*/

	printf("Hit any key to quit\n");
	getchar();
}

int main (int argc, char* argv[])
{
	Echo echo_service = CORBA_OBJECT_NIL;
	CORBA_Environment ev[1];
	CORBA_char filename[] = "echo.ref";
        
        CORBA_exception_init(ev);

	linc_set_threaded(TRUE);

	client_init (&argc, argv, &global_orb, ev);
	etk_abort_if_exception(ev, "init failed");

	g_print ("Reading service reference from file \"%s\"\n", filename);

	echo_service = (Echo) etk_import_object_from_file (global_orb,
							   filename,
							   ev);
        etk_abort_if_exception(ev, "import service failed");

	client_run (echo_service, ev);
        etk_abort_if_exception(ev, "service not reachable");
 
	client_cleanup (global_orb, echo_service, ev);
        etk_abort_if_exception(ev, "cleanup failed");
 
        exit (0);
}
#include <stdio.h>
#include <stdlib.h>

#include "echo.h"

int niters = 10000;
int nthreads = 8;
char *server_ior;
CORBA_ORB orb;

static gpointer
echo_client_thread (gpointer data)
{

	int i;
	Echo echo_client;
	CORBA_Environment *ev, real_ev;

	CORBA_exception_init ((ev = &real_ev));

	echo_client = CORBA_ORB_string_to_object (orb, server_ior, ev);
	if (!echo_client) {
		g_error ("[%p]: Cannot bind to %s\n",
			 g_thread_self (), server_ior);
		return NULL;
	}
	
	for (i = 0; i < 4; i++) /* let others get started */
		g_thread_yield ();

	for (i = 0; i < niters; i++) {
		char *str;
		CORBA_double tmp;
		Echo retval;
		str = g_strdup_printf ("[%p]: Hello, world [%d]",
				       g_thread_self (), i);

		Echo_doOneWay (echo_client, str, ev);
		
		retval = Echo_echoString (echo_client, str, &tmp, ev);

		g_free (str);

		if (ev->_major != CORBA_NO_EXCEPTION) {
			g_error ("[%p]: we got exception %s from echoString!\n",
				 g_thread_self (), ev->_id);
			return NULL;
		}

		CORBA_Object_release (retval, ev);
	}

	CORBA_Object_release (echo_client, ev);

	return data;
}

int
main (int argc, char *argv[])
{
	int i;
	GError *error = NULL;
	GThread **threads;
	CORBA_Environment *ev, real_ev;

	CORBA_exception_init ((ev = &real_ev));

	orb = CORBA_ORB_init (&argc, argv, "orbit-local-mt-orb", ev);

	if (argc < 2) {
		g_error ("Syntax: %s <server IOR> [<niters> [<nthreads>] ]\n",
			 argv [0]);
		return 1;
	}
	server_ior = argv [1];

	if (argc >= 3)
		niters = atoi (argv [2]);

	if (argc >= 4)
		nthreads = atoi (argv [3]);

	threads = g_new0 (GThread *, nthreads);

	for (i = 0; i < nthreads; i++) {
		threads [i] = g_thread_create (
			echo_client_thread, &threads[i],
			TRUE, &error);
		if (error)
			g_error ("Error spawning threads '%s'", 
				 error->message);
	}

	###
	### Add this will hang the program at some point .... ?????
	###
	echo_client_thread(NULL);

	for (i = 0; i < nthreads; i++) {
		if (!(g_thread_join (threads [i]) == &threads [i]))
			g_error ("Wierd thread join problem '%d'", i);
	}

	CORBA_ORB_destroy (orb, ev);
	CORBA_Object_release ((CORBA_Object) orb, ev);

	return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]