Succinct, Simple Semaphor Sought

I update my main repos when I log in anywhere. This usually works fine, but some logins kick off two terminals at once, and then the updates in one would fail while the other worked. (And often they alternate failing and working: you see why, right?)

This is really no problem... but it offends my aesthetic sensibilities. I should just be attempting these updates once, right? So I tried a very simple semaphor:


#!/bin/sh

export REPO_SEM="repo_semaphore"

# let's update our main repos:
if [ ! -e $REPO_SEM ]
then
# set a semaphore:
    touch $REPO_SEM

    cd $GDIR/algorithms; git pull origin master
 # more updates done here...

    cd $HOME; rm $REPO_SEM
else
    echo "$REPO_SEM exists: another processes may be doing the update."
fi

This works... except when I really need it to, when the two logins kick off simultaneously. In the time between the existence test and the touch, both logins are able to proceed. What I would really need is for the if and the touch to be atomic, but there's no way to do that in a shell script, right?

Anyone know how to do this correctly?

Comments

  1. Well, it's been a while ...
    This isn’t a real atomic action semaphore.
    There's a race between the -e and the touch. Can you test the pid of the touched file? If so you could add a test on that as optimistic locking.

    As I recall there was a real semaphore in Unix, some versions at least. I have used it decades ago but from a C program called by the script and it was perfect.

    ReplyDelete
    Replies
    1. "This isn’t a real atomic action semaphore.
      There's a race between the -e and the touch."

      Well, yes, that's what I pointed out in my post!

      Delete
    2. "when the two logins kick off simultaneously. In the time between the existence test and the touch, both logins are able to proceed. What I would really need is for the if and the touch to be atomic..."

      Delete
  2. Forgive me posting a solution I have not tried myself, but this looks useful:

    "atomic create file if not exists from bash script"

    https://stackoverflow.com/questions/13828544/atomic-create-file-if-not-exists-from-bash-script

    Basically, use 'mkdir' or 'set -o noclobber'

    ReplyDelete
  3. If you are on Linux you may have the flock command installed. Try that.

    ReplyDelete

Post a Comment

Popular posts from this blog

Central Planning Works!

Aleph-null bleg