ThreadError: not owner

Hello. I had the following code and it worked in Ruby that came with
some old Windows One-Click Installer (now I don’t know which version it
was):

m=Mutex::new
m.lock
Thread:new
{

something1

m.unlock

something2

}
m.synchronize{}

The main thread was supposed to create a new thread, and then wait for
this thread to complete executing something1. But now (RUBY_PATCHLEVEL
#=> 287) the unlock done from the new thread raises ThreadError: not
owner.

OK, that’s true that I try to lock and unlock the mutex in two distinct
threads, but is it that bad? Now I need some other way to synchronise
the threads.

I cannot take something1 out of the second thread, because the whole
content of the second thread is in fact wrapped in some begin rescue
clauses, and I don’t want to break the scoping, too. The only solution I
can think of now is this:

Thread:new
{

something1

Thread.main.wakeup

something2

}
sleep

But now I risk calling wakeup before the main thread gets to the sleep
command, which will break the whole thing. Of course I could set up some
flag or something…

Are there any better ideas around? Thanks.

TPR.

Hmmm. I’m guessing that the ability to use a Mutex like a semaphore
wad taken away when the Mutex class was rewritten in c. A Semaphore
class should have then also been added to cover this other use case,
if that ability has to be removed, but I don’t see one in my
installation. Signalling is the other important use case for
semaphores besides mutual exclusion. I’d say this is a bug. (But then,
who am I?)

Luckily for you, there’s an implementation of Semaphore in ruby here:
http://www.imasy.or.jp/~fukumoto/ruby/semaphore.rb

I can’t vouch for that code at all. Note that since it’s written in
ruby, it’s going to be very slow, compared to the new mutexes… but
then you were using the old (slow) mutexes before so at least you
should be no worse off. Also, Thread.critical is very bad for jruby,
so don’t use this there.

You’ll have to create a separate variable to hold the semaphore,
something like this: (untested!)

m=Mutex::new
sem=Semaphore.new
Thread.new {

something1

sem.signal

something2

}
sem.wait
m.synchronize{}

Maybe you don’t even need the mutex at all now. I can’t tell from this
little example.

Thomas B. wrote:

Are there any better ideas around? Thanks.

Would a Monitor do the job?

http://www.ruby-doc.org/stdlib/libdoc/monitor/rdoc/index.html

Thanks for your responses.

Caleb C. wrote:

Hmmm. I’m guessing that the ability to use a Mutex like a semaphore
wad taken away when the Mutex class was rewritten in c. A Semaphore
class should have then also been added to cover this other use case,
if that ability has to be removed, but I don’t see one in my
installation. Signalling is the other important use case for
semaphores besides mutual exclusion. I’d say this is a bug. (But then,
who am I?)

That’s really strange, I thought there is some mechanism for doing this
and I will get a quick response from somebody who knows it. Also, I
didn’t find any info about the change in Mutex functionality anywhere,
and note that the change happened somewhere inside 1.8.6 - my old Ruby
was 1.8.6 and it worked, and my current version is also 1.8.6 (release
date 2008-08-11) and it doesn’t.

Luckily for you, there’s an implementation of Semaphore in ruby here:
http://www.imasy.or.jp/~fukumoto/ruby/semaphore.rb

Thanks, I’ll test it later. In this case I don’t need it to be fast,
this is an initialisation and happens not more than several times in the
program. But there is a problem with the example code you provided,
because you do not ensure that the main thread enters the wait state
before the semaphore is signalled.

My current solution is like this:

m=Mutex::new
thr=Thread:new
{
m.lock

something1

m.unlock

something2

}
Thread.pass until m.locked? or not thr.alive?
m.synchronize{}

The initial loop ensures that the second thread locks the mutex before
the main thread does it (by synchronize). I guess it is not perfect, but
it works.

Unfortunately, Monitor does not allow this way of usage, too.

TPR.

On 9/22/08, Thomas B. [email protected] wrote:

Thanks for your responses.
[snip]
Unfortunately, Monitor does not allow this way of usage, too.

Really? After I looked into it, it seemed like maybe you could use a
condition variable, but then I’ve never understood monitors or
condition variables properly. A semaphore seems so much simpler, for
this case, at any rate. I guess condition variables would have the
advantage of being faster, (if they can be made to work) since they
were presumably rendered into c as well.

Caleb C. wrote:

On 9/22/08, Thomas B. [email protected] wrote:

Thanks for your responses.
[snip]
Unfortunately, Monitor does not allow this way of usage, too.

Really? After I looked into it, it seemed like maybe you could use a
condition variable, but then I’ve never understood monitors or
condition variables properly. A semaphore seems so much simpler, for
this case, at any rate. I guess condition variables would have the
advantage of being faster, (if they can be made to work) since they
were presumably rendered into c as well.

As far as I know, the only difference between Mutex and Monitor in Ruby
(apart from the internal implementation, I mean) is that Monitors are
reentrant, meaning that a monitor can not only be locked or unlocked,
but it can also be locked multiple times, if all the locks come from the
same thread, so you can do this:
mon.synchronize{mon.synchronize{x}} and get no deadlock or anything. But
still it has to be unlocked by the same thread that locked it.

As for condition variables, I don’t think they could help in my
situation. It’s not what they are designed for, if I understand them
well. I think that the Semaphore (or maybe I’ll write my own Semaphore
class) is the best solution here, only I hoped for a core class for
doing this.

Thomas B. wrote:

But there is a problem with the example code you provided,
because you do not ensure that the main thread enters the wait state
before the semaphore is signalled.

I’m sorry, my mistake. It will work no matter which happens first, as
the semaphore stays signalled even if no thread is currently waiting. My
first glance at the code reported otherwise.

The case I described is really a problem only when using my strange
construction with mutex or sleep.

TPR.

Brian C. wrote:

q = Queue.new
Thread.new do

something1

q.push(:dummy)

something2

end
q.pop

Thanks! That seems to be a good solution.

The name Queue is a bit confusing…

TPR.

Thomas B. wrote:

m=Mutex::new
m.lock
Thread:new
{

something1

m.unlock

something2

}
m.synchronize{}

The main thread was supposed to create a new thread, and then wait for
this thread to complete executing something1.

Hmm, so you just need some way for the thread to signal that it has
finished something1? I’d suggest

q = Queue.new
Thread.new do

something1

q.push(:dummy)

something2

end
q.pop

The semantics of a queue are very easy to understand :slight_smile:

Thomas B. wrote:

Brian C. wrote:

q = Queue.new
Thread.new do

something1

q.push(:dummy)

something2

end
q.pop

Thanks! That seems to be a good solution.

The name Queue is a bit confusing…

That’s what it is - a first-in, first-out queue. However it is nicely
thread-safe, and the ‘pop’ operation blocks until there is something to
retrieve, which is what you need here.