[omniORB] omni_thread memory leak?

Paul Nader naderp@d22mail.alcatel.com.au
Thu, 19 Mar 1998 19:13:10 +1100 (EST)


Hi,

Is there a known bug iun relation to omni_thread not releasing memory
when a run_undetached method terminates?

I have an object A which creates another object B which inherits from 
omni_thread. In B's constructor I pass a pointer to A and a pointer to
a method of A. A then invoques the start_undetached methof of B. 
B's run_undetached method executes the method passed in its construtor
(this is the only way I can think of getting around the fact that all
of the signatures in omni_thread refer to pointers to functions rather
than pointers to methods).

A then signals B to exit and calls B->join(). B exits from the run_undetached 
method, joins A. I then delete A.

Both destructors are called but the program leaks memory by the bucket load.
I've included the program below, and an execution trace as well.

Anyone have any ideas what I might be doing wrong?

Thanks, Paul.

Here's the trace :

Object Constructor : start
Dispatcher cosntructor : start
Dispatcher cosntructor : end
Object Constructor : end
Object shutdown : start
Dispatcher run_undetached : start
Object _dispatch : start
Object _dispatch : end
Dispatcher run_undetached : start
Dispatcher destructor : start
Dispatcher destructor : end
Object shutdown : end
Object Destructor : start
Object Destructor : end
...
same trace repeated over and over again...

Here's the program :

#include "omnithread.h"
#include <iostream.h>

class Object {

public:
  Object();
  ~Object();
  omni_mutex lock;
  omni_condition shut;
  void shutdown(void);
  friend class Dispatcher;
  int shuttingDown;

private:
  Dispatcher *_dispatcher;
  void _dispatch(void);
};

class Dispatcher : public omni_thread {

public:
  typedef void (Object::*Method)(void);
  Dispatcher(Object *object, Method method);
  void* run_undetached(void *);
  ~Dispatcher();

private:
  Object* _object;
  Method _method;
};

Object::Object() : shut(&lock) {

  cerr << "Object Constructor : start" << endl;
  shuttingDown = 0;
  _dispatcher = new Dispatcher(this, &Object::_dispatch);
  cerr << "Object Constructor : end" << endl;
}

void
Object::_dispatch() {

  cerr << "Object _dispatch : start" << endl;
  while (!shuttingDown) {
     shut.wait();
  }
  cerr << "Object _dispatch : end" << endl;
}

void
Object::shutdown(void) {

  cerr << "Object shutdown : start" << endl;
  shuttingDown = 1;
  shut.signal();
  _dispatcher->join(0);
  cerr << "Object shutdown : end" << endl;
}

Object::~Object() {
  cerr << "Object Destructor : start" << endl;
  cerr << "Object Destructor : end" << endl;
}

Dispatcher::Dispatcher(Object *object, Method method) :
            omni_thread() {

  cerr << "Dispatcher cosntructor : start" << endl;
  _method = method;
  _object = object;
  start_undetached();
  cerr << "Dispatcher cosntructor : end" << endl;
}

void*
Dispatcher::run_undetached (void *) {

  cerr << "Dispatcher run_undetached : start" << endl;
  (_object->*_method)();
  cerr << "Dispatcher run_undetached : start" << endl;
  return(0);
}

Dispatcher::~Dispatcher() {

  cerr << "Dispatcher destructor : start" << endl;
  cerr << "Dispatcher destructor : end" << endl;
}

int main(void) {

  while (1) {
    Object *po = new Object();
    po->shutdown();
    delete po;
  }
}