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

unique_lock & shared_lock #16

Closed
samchon opened this issue Nov 10, 2018 · 2 comments
Closed

unique_lock & shared_lock #16

samchon opened this issue Nov 10, 2018 · 2 comments
Labels
C++11 C++14 enhancement New feature or request help wanted Extra attention is needed question Further information is requested
Projects

Comments

@samchon
Copy link
Owner

samchon commented Nov 10, 2018

In C++ STL, unique_lock & shared_lock ensures safety locks using destruction pattern. However, unlike C++, JS does not support the destructor, thus TSTL should design alternative solutions for those safety locks.

My answer is to using closure function for the safety lock. However, I haven't determined the detailed solution yet. I've two candidate solutions. Which one would be better? I'm looking forward to your ideas and opinions.

1. Global Functions in Namespace

type Closure = () => void | Promise<void>;
interface Mutex
{
    lock(): Promise<void>;
    unlock(): Promise<void>;
    
    try_lock?(): Promise<boolean>;
    try_lock_for?(ms: number): Promise<boolean>;
    try_lock_until?(at: Date): Promise<boolean>;
}

namespace std.unique_lock
{
    export async function lock(mtx: Mutex, task: Closure): Promise<void>
    {
        await mtx.lock();
        await task();
        await mtx.unlock();
    }
    export function try_lock(mtx: Mutex, task: Closure): Promise<boolean>;
    export function try_lock_for(mtx: Mutex, ms: number, task: Closure): Promise<boolean>;
    export function try_lock_until(mtx: Mutex, ms: number, task: Closure): Promise<boolean>;
}

2. Class providing Lambda Methods

type Task = () => void | Promise<void>;
interface SharedMutex
{
    lock_shared(): Promise<void>;
    unlock_shared(): Promise<void>;
    
    try_lock_shared?(): Promise<boolean>;
    try_lock_shared_for?(ms: number): Promise<boolean>;
    try_lock_shared_until?(at: Date): Promise<boolean>;
}

class SharedLock
{
    private mtx_: SharedMutex;
    public constructor(mutex: SharedMutex);

    public lock(task: Closure): Promise<void>;
    public try_lock(task: Closure): Promise<boolean>;
    public try_lock_for?(ms: number, task: Closure): Promise<boolean>;
    public try_lock_until?(at: Date, task: Closure): Promise<boolean>
    {
        let ret: Boolean = await this.mtx_.try_lock_shared_until(at);
        if (ret)
        {
            await task();
            await this.mtx_.mtx_.unlock_shared();
        }
        return ret;
    }
}
@samchon samchon added help wanted Extra attention is needed v2.1 C++11 question Further information is requested and removed help wanted Extra attention is needed question Further information is requested v2.1 labels Nov 10, 2018
@samchon samchon added this to In progress in v2.1 Update Nov 13, 2018
@samchon samchon moved this from In progress to Done in v2.1 Update Nov 27, 2018
@samchon
Copy link
Owner Author

samchon commented Nov 27, 2018

I'm planning to adapt the 1st way. You've an another idea or opposite opinion, then please tell me.

@samchon samchon moved this from Done to On review in v2.1 Update Nov 30, 2018
@samchon samchon moved this from On review to Done in v2.1 Update Dec 5, 2018
@samchon samchon moved this from Done to On review in v2.1 Update Dec 6, 2018
@samchon samchon added C++14 help wanted Extra attention is needed and removed help wanted Extra attention is needed labels Dec 11, 2018
@samchon
Copy link
Owner Author

samchon commented Dec 11, 2018

I decided to adapt both of them all. Type restriction would be enhanced like such below:

export class SharedLock<Mutex extends IMutex>
{
    public constructor(mutex: Mutex);

    public lock(closure: Closure): Promise<void>;
    public try_lock(closure: Closure): Promise<boolean>;

    public try_lock_for: "try_lock_shared_for" extends keyof Mutex
        ? (ms: number, closure: Closure) => Promise<boolean>
        : undefined;
    
    public try_lock_until: "try_lock_shared_until" extends keyof Mutex
        ? (at: Date, closure: Closure) => Promise<boolean>
        : undefined;
}

export namespace SharedLock
{
    export function lock<Mutex extends Pick<_ISharedLockable, "lock_shared"|"unlock_shared">>
        (mutex: Mutex, closure: Closure): Promise<void>;

    export function try_lock<Mutex extends Pick<_ISharedLockable, "try_lock_shared"|"unlock_shared">>
        (mutex: Mutex, closure: Closure): Promise<boolean>;

    export function try_lock_for<Mutex extends Pick<_ISharedTimedLockable, "try_lock_shared_for"|"unlock_shared">>
        (mutex: Mutex, ms: number, closure: Closure): Promise<boolean>;

    export function try_lock_until<Mutex extends Pick<_ISharedTimedLockable, "try_lock_shared_until"|"unlock_shared">>
        (mutex: Mutex, at: Date, closure: Closure): Promise<boolean>;
}
export import shared_lock = SharedLock;

interface IMutex
{
    lock_shared(): Promise<void>;
    unlock_sharedO(): Promise<void>;

    try_lock_shared(): Promise<boolean>;
    try_lock_shared_for?(ms: number): Promise<boolean>;
    try_lock_shared_until?(at: Date): Promise<boolean>;
}
type Closure = () => void | Promise<void>;

@samchon samchon added enhancement New feature or request question Further information is requested labels Dec 11, 2018
@samchon samchon moved this from On review to Done in v2.1 Update Dec 11, 2018
@samchon samchon closed this as completed Dec 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C++11 C++14 enhancement New feature or request help wanted Extra attention is needed question Further information is requested
Projects
No open projects
v2.1 Update
  
Done
Development

No branches or pull requests

1 participant