[p4] Race condition with p4 counters

Stephen Vance steve at vance.com
Thu Apr 3 15:17:49 PDT 2008


Rick --

I'm pretty sure it hides the race condition it's trying to avoid with 
another race condition on the guard lock. Practically, it's probably a 
little safer, but will still fail under heavy load.

Steve

Rick Macdonald wrote:
> Two years ago I submitted a suggestion to have an atomic 
> "get-next-value" for counters. They replied that they are considering it 
> for the future and added my name to the list of people who have asked 
> for this. As far as I can see, it has not been done.
>
> In the shower this morning, I came up with this idea, which surely must 
> be done atomically within the Perforce server:
>
> $ p4 job -o | sed -e 's/<enter description here>/Temporary job to get 
> next Job counter and increment it./' | p4 job -i
> Job job000007 saved.
> (parse the message above to get the job number)
> $ p4 job -d job000007
>
> I think this will work for me. I don't care about monotonically 
> increasing numbers for anything that I need these counters for 
> (including Jobs, because I'll use a different prefix anyway). It's three 
> p4 command executions, but we'd only do this a few times a day.
>
> Has anybody found a better idea?
>
> Here is an unsupported script that Perforce send me, but I think it 
> still suffers from a race condition. Am I wrong?
>
> import os, time
>  
>         # wait for foolock counter to be set to zero
>         # if it times out, just go ahead and grab the lock
>         timeout = 4
>         while int(os.popen('p4 counter foolock').read()) != 0 and 
> timeout>0:
>           print 'attempting to get lock...'
>           timeout = timeout - 1
>           time.sleep(1)
>         if timeout == 0: print 'breaking lock'
>  
>         # grab lock
>         os.popen('p4 counter foolock 1')
>         if not int(os.popen('p4 counter foolock').read()) == 1:
>           raise 'unable to obtain lock!'
>  
>         # get and increment foo counter
>         foo = int(os.popen('p4 counter foo').read()) + 1
>         os.popen('p4 counter foo %d' % foo)
>         if not int(os.popen('p4 counter foo').read()) == foo:
>           raise 'unable to set foo counter!'
>  
>         # release lock
>         os.popen('p4 counter -d foolock')
>         if not int(os.popen('p4 counter foolock').read()) == 0:
>           raise 'unable to release lock!'
> _______________________________________________
> perforce-user mailing list  -  perforce-user at perforce.com
> http://maillist.perforce.com/mailman/listinfo/perforce-user
>
>   

-- 
Stephen Vance
www.vance.com


More information about the perforce-user mailing list