[plt-scheme] Calling virtual C++-functions from other MzScheme-threads

From: Daniel K. Skovenborg (waldeinburg at yahoo.com)
Date: Fri Nov 21 19:05:26 EST 2003

Hello

I have encountered a problem I don't understand: Creating an instance of
a polymorphic class in a MzScheme-thread and then calling a virtual
member-function of this object in another thread triggers a segmentation
fault. Calling the same function inside the program does not trigger the
problem.

I've read through the documents about threads in MzScheme and different
information about virtual functions, but I still can't figure out what
happens. What is going on when calling scheme-functions since this can
happen? And is there any way to call virtual member-functions from other
threads without triggering the problem?

The example in the end of this mail (I know it's not pretty, but it
works) triggers the problem when making the following session:

(thread (lambda () (tfoo))) => "A::foo"
(test) => segfault

When A::foo is called from tfoo there's no problem. Try to remove the
virtual keyword and it will also work when called from 'test'.

This small example can't show, that calling pa->foo() inside the program
works fine, but I know from my larger program, where I encountered the
problem, that it is possible.

Thanks for your time
Daniel Kjøller Skovenborg


//// start of test.cpp

#include <iostream>
#include <scheme.h>

class A
{
public:
  virtual void foo (void)
  {
    std::cout << "A::foo" << std::endl;
  }
};


A * pa;


Scheme_Object * tfoo (int argc, Scheme_Object * argv [])
{
  A a ;
  pa = & a;
  pa->foo ();

  while (true)
    {
      SCHEME_USE_FUEL (1);
    }

  return scheme_void;
};


Scheme_Object * test (int argc, Scheme_Object * argv [])
{
  pa->foo ();
  return scheme_void;
};


int main (void)
{
  Scheme_Env * e = scheme_basic_env ();

  scheme_add_global ("test",
		     scheme_make_prim_w_arity (& test, "test", 0, 0),
		     e);

  scheme_add_global ("tfoo",
		     scheme_make_prim_w_arity (& tfoo, "tfoo", 0, 0),
		     e);

  scheme_apply ( scheme_builtin_value("read-eval-print-loop") , 0, NULL);

  return 0;
}

//// end of test.cpp


Posted on the users mailing list.