github.com/tursom/GoCollections@v0.3.10/concurrent/ReentrantLock.go (about)

     1  /*
     2   * Copyright (c) 2022 tursom. All rights reserved.
     3   * Use of this source code is governed by a GPL-3
     4   * license that can be found in the LICENSE file.
     5   */
     6  
     7  package concurrent
     8  
     9  import (
    10  	"fmt"
    11  	"sync"
    12  
    13  	"github.com/tursom/GoCollections/exceptions"
    14  )
    15  
    16  type ReentrantLock struct {
    17  	lock      sync.Mutex
    18  	cond      sync.Cond
    19  	recursion int32
    20  	host      int64
    21  }
    22  
    23  func NewReentrantLock() *ReentrantLock {
    24  	res := &ReentrantLock{
    25  		recursion: 0,
    26  		host:      0,
    27  	}
    28  	res.cond = *sync.NewCond(&res.lock)
    29  	return res
    30  }
    31  
    32  func (rt *ReentrantLock) TryLock() bool {
    33  	id := GetGoroutineID()
    34  	rt.lock.Lock()
    35  	defer rt.lock.Unlock()
    36  
    37  	if rt.host == id {
    38  		rt.recursion++
    39  		return true
    40  	}
    41  
    42  	if rt.recursion == 0 {
    43  		rt.host = id
    44  		rt.recursion = 1
    45  		return true
    46  	}
    47  
    48  	return false
    49  }
    50  
    51  func (rt *ReentrantLock) Lock() {
    52  	id := GetGoroutineID()
    53  	rt.lock.Lock()
    54  	defer rt.lock.Unlock()
    55  
    56  	if rt.host == id {
    57  		rt.recursion++
    58  		return
    59  	}
    60  
    61  	for rt.recursion != 0 {
    62  		rt.cond.Wait()
    63  	}
    64  	rt.host = id
    65  	rt.recursion = 1
    66  }
    67  
    68  func (rt *ReentrantLock) Unlock() {
    69  	rt.lock.Lock()
    70  	defer rt.lock.Unlock()
    71  
    72  	if rt.recursion == 0 || rt.host != GetGoroutineID() {
    73  		panic(exceptions.NewWrongCallHostException(fmt.Sprintf("the wrong call host: (%d); current_id: %d; recursion: %d", rt.host, GetGoroutineID(), rt.recursion)))
    74  	}
    75  
    76  	rt.recursion--
    77  	if rt.recursion == 0 {
    78  		rt.cond.Signal()
    79  	}
    80  }