acquire_lock Function

public function acquire_lock(cache_dir, project_name, wait) result(success)

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: cache_dir
character(len=*), intent(in) :: project_name
logical, intent(in), optional :: wait

Return Value logical


Source Code

    function acquire_lock(cache_dir, project_name, wait) result(success)
        character(len=*), intent(in) :: cache_dir, project_name
        logical, intent(in), optional :: wait
        logical :: success, locked
        character(len=512) :: lock_file
        logical :: should_wait
        integer :: wait_time, unit, iostat, pid
        character(len=32) :: pid_str, timestamp

        should_wait = .true.
        if (present(wait)) should_wait = wait

        lock_file = get_lock_file_path(cache_dir, project_name)
        wait_time = 0
        success = .false.

        ! Ensure cache directory exists (only create if it doesn't exist)
        block
            logical :: dir_exists
            inquire (file=trim(cache_dir), exist=dir_exists)
            if (.not. dir_exists) then
                call mkdir(cache_dir)
            end if
        end block

        do
            ! First check if lock already exists
            inquire (file=lock_file, exist=locked)
            ! DEBUG
            ! print *, 'DEBUG acquire_lock: lock exists=', locked, ' for ', trim(lock_file)
            if (.not. locked) then
                ! Try to create lock file atomically
                if (try_create_lock(lock_file)) then
                    success = .true.
                    exit
                else
                    ! Failed to create, but file doesn't exist - race condition?
                    success = .false.
                    if (.not. should_wait) then
                        exit
                    end if
                end if
            else
                ! Lock exists, check if it's stale
                if (is_lock_stale(lock_file)) then
                    call remove_lock(lock_file)
                    cycle
                end if

                ! Lock exists and is not stale
                success = .false.
                ! DEBUG
                ! print *, 'DEBUG: Lock exists and not stale, setting success=F, should_wait=', should_wait

                ! If not waiting, fail immediately
                if (.not. should_wait) then
                    exit
                end if
            end if

            ! Wait and retry
            call sys_sleep(1)
            wait_time = wait_time + 1

            if (wait_time >= MAX_WAIT_TIME) then
                call debug_print('Cache lock timeout after ' // int_to_char(MAX_WAIT_TIME) // ' seconds for ' // trim(project_name))
                exit
            end if
        end do

    end function acquire_lock