Pthread_mutex_lock is causing Kernel#at_exit

Hello,

I have a C program which embeds Ruby inside a pthread. The C program and
Ruby take turns executing and transfer control to each other when
necessary.

During the first time Ruby transfers control to the C program (see
relay_verilog() function below), the Kernel#at_exit method is being
invoked. During subsequent times when Ruby transfers control to the C
program, the Kernel#at_exit method is not invoked.

Now, the problem is that Kernel#at_exit is being triggered too early
(during the first transfer of control) – before the Ruby program even
finishes! The pthread ,which contains Ruby, is activated later by the C
program and the Ruby program keeps running.

In the code below, the C program transfers control to Ruby via the
relay_ruby() function. And Ruby transfers to the C program via the
relay_verilog() function. The full source code can be found here:
http://ruby-vpi.rubyforge.org/src/ruby-vpi/ext/relay.c

Can somebody explain why “freezing” the pthread (which contains Ruby)
causes the Kernel#at_exit to trigger? Is there a way I can avoid this
behavior?

Thanks for your consideration.

---------- code ---------------

pthread_t relay__rubyThread;
pthread_mutex_t relay__rubyLock;
pthread_mutex_t relay__verilogLock;

void relay_init() {
pthread_mutex_init(&relay__rubyLock, NULL);
pthread_mutex_lock(&relay__rubyLock);
pthread_mutex_init(&relay__verilogLock, NULL);
pthread_mutex_lock(&relay__verilogLock);
}

void relay_ruby() {
pthread_mutex_unlock(&relay__rubyLock);
pthread_mutex_lock(&relay__verilogLock);
}

void relay_verilog() {
pthread_mutex_unlock(&relay__verilogLock);
pthread_mutex_lock(&relay__rubyLock);//<-----this is causing
Kernel#at_exit
}

Suraj K. wrote:

During the first time Ruby transfers control to the C program (see
relay_verilog() function below), the Kernel#at_exit method is being
invoked. During subsequent times when Ruby transfers control to the C
program, the Kernel#at_exit method is not invoked.

Sorry, there is nothing wrong with pthread_mutex_lock and
Kernel#at_exit – I was mistaken.

The real problem is that I had forgotten that Kernel#at_exit runs the
blocks passed to it in reverse order. So I was getting behavior that
seemed like pthread_mutex_lock was causing Kernel#at_exit to trigger.
This is purely coincidental.

Sorry for the trouble.