LCOV - code coverage report
Current view: top level - pebble/vfs - file_lock_unix.go (source / functions) Hit Total Coverage
Test: 2023-12-31 08:15Z 1cce3d01 - meta test only.lcov Lines: 0 34 0.0 %
Date: 2023-12-31 08:16:35 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2014 The LevelDB-Go and Pebble Authors. All rights reserved. Use
       2             : // of this source code is governed by a BSD-style license that can be found in
       3             : // the LICENSE file.
       4             : 
       5             : //go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
       6             : // +build darwin dragonfly freebsd linux netbsd openbsd solaris
       7             : 
       8             : package vfs
       9             : 
      10             : import (
      11             :         "io"
      12             :         "os"
      13             :         "sync"
      14             : 
      15             :         "github.com/cockroachdb/errors"
      16             :         "golang.org/x/sys/unix"
      17             : )
      18             : 
      19             : var lockedFiles struct {
      20             :         mu struct {
      21             :                 sync.Mutex
      22             :                 files map[string]bool
      23             :         }
      24             : }
      25             : 
      26             : // lockCloser hides all of an os.File's methods, except for Close.
      27             : type lockCloser struct {
      28             :         name string
      29             :         f    *os.File
      30             : }
      31             : 
      32           0 : func (l lockCloser) Close() error {
      33           0 :         lockedFiles.mu.Lock()
      34           0 :         defer lockedFiles.mu.Unlock()
      35           0 :         if !lockedFiles.mu.files[l.name] {
      36           0 :                 panic(errors.Errorf("lock file %q is not locked", l.name))
      37             :         }
      38           0 :         delete(lockedFiles.mu.files, l.name)
      39           0 : 
      40           0 :         return l.f.Close()
      41             : }
      42             : 
      43           0 : func (defaultFS) Lock(name string) (io.Closer, error) {
      44           0 :         lockedFiles.mu.Lock()
      45           0 :         defer lockedFiles.mu.Unlock()
      46           0 :         if lockedFiles.mu.files == nil {
      47           0 :                 lockedFiles.mu.files = map[string]bool{}
      48           0 :         }
      49           0 :         if lockedFiles.mu.files[name] {
      50           0 :                 return nil, errors.New("lock held by current process")
      51           0 :         }
      52             : 
      53           0 :         f, err := os.Create(name)
      54           0 :         if err != nil {
      55           0 :                 return nil, err
      56           0 :         }
      57           0 :         spec := unix.Flock_t{
      58           0 :                 Type:   unix.F_WRLCK,
      59           0 :                 Whence: io.SeekStart,
      60           0 :                 Start:  0,
      61           0 :                 Len:    0, // 0 means to lock the entire file.
      62           0 :                 Pid:    int32(os.Getpid()),
      63           0 :         }
      64           0 :         if err := unix.FcntlFlock(f.Fd(), unix.F_SETLK, &spec); err != nil {
      65           0 :                 f.Close()
      66           0 :                 return nil, err
      67           0 :         }
      68           0 :         lockedFiles.mu.files[name] = true
      69           0 :         return lockCloser{name, f}, nil
      70             : }

Generated by: LCOV version 1.14