From: "Mauricio Fernández" Date: 2003-08-25T15:27:01+09:00 Subject: Re: How did this variable become negative? On Mon, Aug 25, 2003 at 10:54:46AM +0900, Philip Mak wrote: > So that means @@num_sending must have become -1 somehow, in order for > a ZeroDivisionError to occur. > > But @@num_sending is initialized to 0, and this is the only place in > the code where it is modified: > > begin > @@num_sending += 1 > yield limit > ensure > @@num_sending -= 1 > end > > So how could @@num_sending have become -1? It can only be decremented > after being incremented. Could the fact that this class is used by > multiple threads simultaneously have something to do with it? But I > still don't see how it could happen... As you point out, your code is not threads-safe Consider the following scenario: * 2 threads, called A and B * thread A is the first to enter that section of code. In order to do @@num_sending += 1, it first grabs @@num_sending (which is 0) and then adds 1 (ie. it's not an atomic operation). Imagine that just after A takes the value of @@num_sending, B does the same. You'll then have the following A B take @@num_sending => 0 take @@num_sending => 0 add 1 store 1 in @@num_sending (@@num_sending = 1 here) add 1 store 1 in @@num_sending (@@num_sending = 1 here) Now, the -= 1 operations could happen "atomically" (no thread switching in the middle), then take value => 1 substract 1 store (0) take value => 0 substract 1 store -1 The solution is changing your code or using a mutex. -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com I did this 'cause Linux gives me a woody. It doesn't generate revenue. -- Dave '-ddt->` Taylor, announcing DOOM for Linux