github.com/keysonzzz/kmg@v0.0.0-20151121023212-05317bfd7d39/kmg/SubCommand/serviceCmd/lock.go (about)

     1  package serviceCmd
     2  
     3  import (
     4  	"github.com/bronze1man/kmg/kmgFile"
     5  	"github.com/bronze1man/kmg/kmgRand"
     6  	"path/filepath"
     7  	"time"
     8  )
     9  
    10  type FileMutex struct {
    11  	isOwner  bool
    12  	filePath string
    13  }
    14  
    15  func (fm *FileMutex) Lock(name string) {
    16  	fm.filePath = filepath.Join("/tmp", name)
    17  	if !fm.isLock() {
    18  		fm.ownAndLock()
    19  		return
    20  	}
    21  	if fm.isOwner {
    22  		return
    23  	} else {
    24  		fm.waitToUnLock()
    25  		fm.ownAndLock()
    26  	}
    27  }
    28  
    29  func (fm *FileMutex) UnLock() {
    30  	if !fm.isOwner {
    31  		return
    32  	}
    33  	fm.isOwner = false
    34  	kmgFile.MustDelete(fm.filePath)
    35  }
    36  
    37  func (fm *FileMutex) waitToUnLock() {
    38  	i := 0
    39  	for {
    40  		i++
    41  		if !fm.isLock() {
    42  			break
    43  		} else {
    44  			time.Sleep(time.Second)
    45  		}
    46  		if i > 60 {
    47  			panic("FileMutex wait for UnLock timeout")
    48  		}
    49  	}
    50  }
    51  
    52  func (fm *FileMutex) isLock() bool {
    53  	time.Sleep(time.Duration(kmgRand.IntBetween(0, 1000)) * time.Millisecond)
    54  	if kmgFile.MustFileExist(fm.filePath) {
    55  		return true
    56  	}
    57  	return false
    58  }
    59  
    60  func (fm *FileMutex) ownAndLock() {
    61  	kmgFile.MustWriteFile(fm.filePath, []byte("1"))
    62  	fm.isOwner = true
    63  }