Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UniqueLock.lock & SharedLock.lock are dangerous #42

Closed
samchon opened this issue Jul 17, 2019 · 0 comments
Closed

UniqueLock.lock & SharedLock.lock are dangerous #42

samchon opened this issue Jul 17, 2019 · 0 comments
Assignees
Labels
bug Something isn't working C++11 C++14 enhancement New feature or request
Projects

Comments

@samchon
Copy link
Owner

samchon commented Jul 17, 2019

Summary

  • TSTL Version: 2.2.1
  • Expected behavior: _SafeLock.lock() holds locker until be free
  • Actual behavior: _SafeLock.lock() may not hold the critical section
  • Solution: _SafeLock.lock() must have its identical implementation code.

Code occuring the danger

Detailed Story

UniqueLock.lock() and SharedLock.lock() are inline functions of base._SafeLock.lock() and the base._SafeLock.lock() is an inline function of base._SafeLock.try_lock(), too. It seems dangerous implementation considering characteristics of the final destination function base._SafeLock.try_lock()

  • UniqueLock.lock() -> base._SafeyLock.lock() -> base._SafeLock.try_lock()
  • SharedLock.lock() -> base._SafeyLock.lock() -> base._SafeLock.try_lock()

export async function try_lock
(
locker: () => Promise<boolean>,
unlocker: () => Promise<void>,
lambda: () => void | Promise<void>
): Promise<boolean>
{
// TRY LOCK
let ret: boolean = await locker();
if (ret === false)
return false;

The base._SafeLock.try_lock() function skips calling lambda if locker returns false. The UniqueLock.lock() and SharedLock.lock() functions, they must hold critical section (locker) until be free. However, they're referencing base._SafeLock.try_lock(), who does not ensure holding critical section in always.

interface ILockable
{
    lock(): Promise<void>;
    unlock(): Promise<void>;
}
interface ISharedLockable
{
    lock_shared(): Promise<void>;
    unlock_shared(): Promise<void>;
}

Only in TypeScript level, it's not danger because the parametric function (locker) type must return Promise<void>. However, let's imagine an extra-ordinary case. There's an user does not use TypeScript and wants to use a custom class. Even the custom class does not follow definition of ILockable (or ISharedLockable) and returns Promise. If the custom class returns false, holding critical section in always is not possible.

Conclusion

To avoid such danger, _SafeLock.lock() must have its identical implementation code.

@samchon samchon added bug Something isn't working C++11 labels Jul 17, 2019
@samchon samchon self-assigned this Jul 17, 2019
@samchon samchon added this to To do in v2.2 Update via automation Jul 17, 2019
@samchon samchon changed the title base._SafeLock (base of UniqueLock & SharedLock) is dangerous base._SafeLock.lock is dangerous Jul 17, 2019
@samchon samchon added the enhancement New feature or request label Jul 17, 2019
@samchon samchon changed the title base._SafeLock.lock is dangerous base._SafeLock.lock seems dangerous Jul 17, 2019
@samchon samchon changed the title base._SafeLock.lock seems dangerous UniqueLock.lock & SharedLock.lock are dangerous Jul 17, 2019
@samchon samchon added the C++14 label Jul 17, 2019
samchon pushed a commit that referenced this issue Jul 17, 2019
@samchon samchon moved this from To do to In progress in v2.2 Update Jul 17, 2019
v2.2 Update automation moved this from In progress to Done Jul 28, 2019
@samchon samchon moved this from Done to Patch in v2.2 Update Jul 28, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working C++11 C++14 enhancement New feature or request
Projects
No open projects
v2.2 Update
  
Patch
Development

No branches or pull requests

1 participant