Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/toolkit/crashreporter/crashping/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 3 kB image not shown  

Quelle  single_instance.rs

  Sprache: Rust
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


//! The Glean DB can only be accessed by one process at a time, so this module offers a simple way
//! to negotiate this (allowing other processes to wait).
//!
//! TODO: Use std file locking when the MSRV is >=1.89.

use std::{
    fs::{File, OpenOptions},
    io::{Result, Write},
    path::Path,
    process,
};

pub struct SingleInstance {
    lockfile: File,
}

impl SingleInstance {
    pub fn acquire(path: &Path) -> Result<Self> {
        let mut lockfile = OpenOptions::new()
            .read(true)
            .write(true)
            .create(true)
            .open(path)?;

        lock(&lockfile)?;
        write!(&mut lockfile, "{}", process::id())?;
        Ok(SingleInstance { lockfile })
    }

    pub fn retain_until_application_exit(self) {
        std::mem::forget(self);
    }
}

impl Drop for SingleInstance {
    fn drop(&mut self) {
        // Don't attempt to delete the file, as there are races that can't be avoided if we do.
        let _ = self.lockfile.set_len(0);
        if let Err(e) = unlock(&self.lockfile) {
            log::error!("failed to unlock lockfile: {e}");
        }
    }
}

#[cfg(unix)]
mod unix {
    use std::ffi::c_int;
    use std::fs::File;
    use std::io::{Error, Result};
    use std::os::fd::AsRawFd;

    const LOCK_EX: c_int = 2;
    const LOCK_UN: c_int = 8;

    extern "C" {
        fn flock(fd: c_int, operation: c_int) -> c_int;
    }

    pub fn lock(file: &File) -> Result<()> {
        let result = unsafe { flock(file.as_raw_fd(), LOCK_EX) };
        (result == 0).then_some(()).ok_or_else(Error::last_os_error)
    }

    pub fn unlock(file: &File) -> Result<()> {
        let result = unsafe { flock(file.as_raw_fd(), LOCK_UN) };
        (result == 0).then_some(()).ok_or_else(Error::last_os_error)
    }
}

#[cfg(unix)]
use unix::{lock, unlock};

#[cfg(windows)]
mod windows {
    use std::ffi::{c_int, c_void};
    use std::fs::File;
    use std::io::{Error, Result};
    use std::os::windows::io::AsRawHandle;

    type HANDLE = *mut c_void;
    type DWORD = u32;
    type BOOL = c_int;

    const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 2;

    #[repr(C)]
    struct OVERLAPPED {
        internal: usize,
        internalhigh: usize,
        // Omit the union of the offset fields with the `PVOID Pointer` since we don't need it.
        offset: DWORD,
        offsethigh: DWORD,
        hevent: HANDLE,
    }

    impl Default for OVERLAPPED {
        fn default() -> Self {
            // # Safety
            // A zeroed OVERLAPPED is defined as valid.
            unsafe { std::mem::zeroed() }
        }
    }

    extern "system" {
        fn LockFileEx(
            hfile: HANDLE,
            dwflags: DWORD,
            dwreserved: DWORD,
            nnumberofbytestolocklow: DWORD,
            nnumberofbytestolockhigh: DWORD,
            lpoverlapped: *mut OVERLAPPED,
        ) -> BOOL;

        fn UnlockFileEx(
            hfile: HANDLE,
            dwreserved: DWORD,
            nnumberofbytestounlocklow: DWORD,
            nnumberofbytestounlockhigh: DWORD,
            lpoverlapped: *mut OVERLAPPED,
        ) -> BOOL;
    }

    pub fn lock(file: &File) -> Result<()> {
        let mut overlapped = OVERLAPPED::default();
        let result = unsafe {
            LockFileEx(
                file.as_raw_handle(),
                LOCKFILE_EXCLUSIVE_LOCK,
                0,
                u32::MAX,
                u32::MAX,
                &mut overlapped,
            )
        };
        (result != 0).then_some(()).ok_or_else(Error::last_os_error)
    }

    pub fn unlock(file: &File) -> Result<()> {
        let mut overlapped = OVERLAPPED::default();
        let result =
            unsafe { UnlockFileEx(file.as_raw_handle(), 0, u32::MAX, u32::MAX, &mut overlapped) };
        (result != 0).then_some(()).ok_or_else(Error::last_os_error)
    }
}

#[cfg(windows)]
use windows::{lock, unlock};

Messung V0.5 in Prozent
C=93 H=98 G=95

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.