Re: Keeping server in memory



On Sat, 2001-12-15 at 20:42, Michael Meeks wrote:
> 
> Hi Gustavo,
> 
> On 14 Dec 2001, Gustavo Carneiro wrote:
> >   I'm developing a program that activates a bonobo object. Recently,
> > bonobo's behaviour has changed drastically:
> 
>         Right :-)
> 
> >   - Before, the app would activate the server using bonobo-activation
> > and, when the app left, the server would still be running.
> 
>         Quite probably - this is typicaly extremely sub-optimal, since
> it'll leave servers lying around on the system.
> 
> >   - Now (with a recent bonobo build) , when the app finishes the
> > server also exits and, next time I run the client app, a new server is
> > started.
> 
>         Good :-)
> 
> >   Is this behaviour intentional, or do I have a bug in my app? How I
> > can I get the old behaviour back?
> 
>         Ok - so, you probably do want to quit your server after a while;
> the trick is that the auto factory macros now do this for you:
> 
>         BonoboGenericFactory *factory;
> 
>         factory = bonobo_generic_factory_new (
>                 act_iid, factory_cb, user_data);
> 
>         if (factory) {
>                 bonobo_running_context_auto_exit_unref (
>                         BONOBO_OBJECT (factory));
> 
>                 bonobo_main ();
> 
>                 return bonobo_debug_shutdown ();
>         } else
>                 return 1;
> 
>         You just want to kill the 'auto_exit_unref' in this code - I would
> strongly suggest that you do hook the 'all objects dead' condition and
> perhaps timeout then before exiting - it's really bad news to leave stale
> processes around.

  Thanks for the reply!
  Your answer leaves me with more questions! :)

  I think, with the help of "the source", I figured how to make the
server stay in memory and exit after some time of inactivity. Please see
attachment. I connected the 'last_unref' signal of the
bonobo_running_context. I also called
   bonobo_running_context_ignore_object (BONOBO_OBJREF (bonobo_running_context));
because it is in the implementation of the function 
   bonobo_running_context_auto_exit_unref (BonoboObject *object)
in bonobo-running-context.c.

   Two problems I encountered with this:
	1- There is a non-static variable declaration in
bonobo-running-context.c:
		BonoboObject *bonobo_running_context = NULL;
which is not declared in the header file. The header file itself,
bonobo-running-context.h, is not even installed!

	2- It works fine, except for the following problem. When my client
quits, it unrefs the server. The 'last_unref' handler is called. After a
timeout, the server exits. So far so good. The problem arises when the
client reconnects before the timeout expires. In that scenario, the
'last_unref' signal has already been emitted once and is not emitted
again at the second time the client exits. I found this in the source
(bonobo-running-context.c):
!	if (!ri->emitted_last_unref &&
!	    (g_hash_table_size (ri->objects) == 0) &&
!	    (g_hash_table_size (ri->keys) == 0)) {
!
!		ri->emitted_last_unref = TRUE;
This seems to be causing this problem. Can it be fixed? Or is it my app
that needs fixing (I wouldn't be surprised:) ?

  One final question. The time value for keeping the server before
quitting is hardcoded, but I would like to make it slightly
configurable. I was thinking about a command-line option. But how do I
pass arguments to the factory in the .server file? I have this at the
moment:
<oaf_server iid="OAFIID:Numexp_KernelFactory" type="exe" 
	location="numexp-kernel">
 (...)
	Can I pass arguments the server in the location="..." attribute?

  Thanks again for any reply.

-- 
Gustavo João Alves Marques Carneiro
<gjc inescporto pt> <gustavo users sourceforge net>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#include "numexp-kernel.h"

#define EXIT_TIMEOUT 10000

static guint exit_timeout_id = 0;

/* #include <bonobo-running-context.h> */
extern BonoboObject *bonobo_running_context;



static BonoboObject* numexp_kernel_factory(BonoboGenericFactory *this_factory,
					   const char *iid, gpointer user_data)
{
    if (strcmp(iid, "OAFIID:Numexp_Kernel") == 0) {
	BonoboObject* obj;
	obj = BONOBO_OBJECT(numexp_kernel_new());
	if (exit_timeout_id) {
	    g_message("Canceling exit timeout because of new request");
	    g_source_remove(exit_timeout_id);
	    exit_timeout_id = 0;
	}
	return obj;
    }
    return NULL;
}

/* BONOBO_OAF_FACTORY("OAFIID:Numexp_KernelFactory", */
/* 		   "numexp-kernel", "1.0", */
/* 		   numexp_kernel_factory, NULL); */


static gboolean exit_timeout_callback(gpointer data)
{
    BonoboObject *object = BONOBO_OBJECT(data);
    bonobo_object_unref(object);
    bonobo_main_quit();
    g_message("Quitting because of timeout");
    exit_timeout_id = 0;
    return FALSE;
}


static void last_unref_cb(gpointer context, BonoboObject *object)
{
    g_message(__FUNCTION__);
    if (!exit_timeout_id)
	exit_timeout_id = g_timeout_add(EXIT_TIMEOUT, exit_timeout_callback, object);
    else
	g_assert_not_reached();
}



int main(int argc, char *argv[])
{
    BonoboGenericFactory *factory;
 
    if (!bonobo_init(&argc, argv))
	g_error(_("Could not initialize Bonobo"));

    factory = bonobo_generic_factory_new("OAFIID:Numexp_KernelFactory",
					 numexp_kernel_factory, NULL);
    
    if (factory) {

	if (bonobo_running_context) {
	    bonobo_running_context_ignore_object(BONOBO_OBJREF(BONOBO_OBJECT(factory)));
		g_signal_connect(G_OBJECT(bonobo_running_context),
				 "last_unref", G_CALLBACK(last_unref_cb),
				 BONOBO_OBJECT(factory));
	}
	  //bonobo_running_context_auto_exit_unref(BONOBO_OBJECT(factory));
	
	bonobo_main();
	
	return bonobo_debug_shutdown();
    } else
	return 1;
}





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