# Pthread\_mutex\_lock is causing Kernel#at\_exit

**URL:** <https://www.ruby-forum.com/t/pthread-mutex-lock-is-causing-kernel-at-exit/79692>\
**Category:** Ruby\
**Created:** [December 18, 2006, 9:35am UTC](https://www.ruby-forum.com/t/pthread-mutex-lock-is-causing-kernel-at-exit/79692 "2006-12-18T09:35:25Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![snk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@snk](https://www.ruby-forum.com/u/snk)\
**Post date:** [December 18, 2006, 9:35am UTC](https://www.ruby-forum.com/t/pthread-mutex-lock-is-causing-kernel-at-exit/79692/1 "2006-12-18T09:35:25Z")

</div>

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](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  
}

---

<div class="post-metadata">

**Author:** ![snk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/d9b06d/32.png) [@snk](https://www.ruby-forum.com/u/snk)\
**Post date:** [December 18, 2006, 8:07pm UTC](https://www.ruby-forum.com/t/pthread-mutex-lock-is-causing-kernel-at-exit/79692/2 "2006-12-18T20:07:17Z")

</div>

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.
