From: Sven Suska Date: 2007-05-19T03:45:39+09:00 Subject: Re: "Crystallizing" Objects Hi, Yohanes Santoso schrieb: >Unless Hash already have an atomic check-before-set >operation, you can't get around it the need of having a lock. [And no, >Hash has no such thing yet. Set#add? is similar to what you're looking >for but it's not atomic]. > > Exactly. I want this atomic check+set. But this is not the only thing that I was trying to achieve by my proposal. I am also very much in favor of multithreadedness to be deeply integrated in the core of Ruby. Look at the ease with which you can write concurrent programs in Erlang. No need to think about locking there -- the language takes care of that. Erlang is based on logic variables, they make this easy. I think that logic variables would not fit well into current Ruby. (But maybe I'm wrong... well, I'd be delighted to have logic variables in Ruby... :-) ) But I think that these "partially frozen" or "crystallizing" objects could be a step towards bringing some of that ease of parallel programming into Ruby. On the whole, I'm very pleased how much attention Erlang gets from the Ruby community currently. I think there's really something that can be learned. Yohanes Santoso schrieb: >Sven Suska writes: > > > >>Sven Suska schrieb: >> >>If it were just a normal hash, we would have to lock the object manually >> >Start locking from this point, before you do a check. > > >> if users.has_key(new_nickname) >> raise "Nickname already exists" >> end >> # hash could be modified here, if not locked!!! >> # if another thread would have stored a user with the same nickname >> # just now, then this data would be overwritten in the next >> statement. >> >> >If you start locking at this point, then in between the check and the >insertion another check and insertion could have occurred and the >following insertion effectively undoes that insertion. > > >> users[new_nickname] = user_data >> Yes, that's what I wanted to say, thanks for elaborating. >>If "users" were in this "partially_frozen" state, then we could write: >> >> begin >> users[new_nickname] = user_data >> rescue CantChangeExistingDataError >> raise "Nickname already exists" >> end >> >> > >For Hash in official ruby implementation, since #= is implemented in C >without any yielding, #= is effectively an atomic operation. But since >you want to throw an exception if there is already existing entry, you'd >still need a lock to do the check-and-insert atomically. > > Yes. Regards, Sven