# Does this lock have a name (related to reader-writer lock)

The object can be locked two different ways, where if the lock is entered the same way a second time, the lock is recursive, but if it's entered the other way, it blocks. Like a reader-writer lock, but symmetric.

In case the text isn't clear, this code should be clear. Beware of bugs. I've only proved it correct, I haven't actually used it yet.

struct mylock {
int counter;
int state;
}

void mylock_acquire(struct mylock *lock, int state)
{
assert(state != 0);
if (lock->state != state) {
lock->state = state;
}
++lock->counter;
}

void mylock_release(struct mylock *lock)
{
if (--lock->counter == 0) {
lock->state = 0;
}
}


This is exactly the same as reader-writer, right down to there being exactly two classes of lock holder, except that the "writer" side is also multi-entry. So I took the core reader-writer code I learned two decades ago and converted it from P-V notation to mutexes and made both sides use the reader-type logic. ratchet freak did catch that it's no longer allowed to unlock a mutex from another thread anymore.

The actual code is different due to using atomic operations, but that complicates the question too much. The sample code is designed to illustrate the lock structure as simply as possible.

If I call up the Debian man page for pthread_mutex_unlock it actually says you can unlock from another thread ("If the mutex is of the "fast" kind, pthread_mutex_unlock always returns it to the unlocked state."), but ratchet freak has pointed out this isn't portable.

What is the name of this kind of lock? If it has a name, it would be helpful for documenting the thing.

• If you've actually proven this code correct, then you should have a formal specification... – Derek Elkins left SE May 29 '19 at 19:50
• @DerekElkins: Formal specification: Do not call fork() while close() is being called. Do not call close() while fork() is being called. Do not deadlock. Do not livelock. Do not starve. – Joshua May 29 '19 at 20:17
• That's not a formal specification. This or this are examples of formal specifications. – Derek Elkins left SE May 29 '19 at 20:36

The code is far from optimal, if you instead use a condition variable it is much clearer:

struct mylock {
int counter;
int state;
}

void mylock_acquire(struct mylock *lock, int state)
{
assert(state != 0);
while (lock->state != 0 && lock->state != state) {
}
lock->state = state;
++lock->counter;
}

void mylock_release(struct mylock *lock)
{
if (--lock->counter == 0) {
lock->state = 0;