Skip to content

Mutexes

Other than Lockables, Pode also lets you create Mutexes. A Mutex lets you control thread synchronisation across different processes, whether they be child-processes; processes running on the current login session; or every process running on the system.

Creating a Mutex

To create a Mutex in Pode you can use New-PodeMutex, this will either create a Mutex or retrieve an existing Mutex if one already exists within the selected scope.

A Mutex will need a -Name but also a -Scope. The default scope is Self, but other options are Local or Global:

Scope Description
Self The current process, or child processes
Local All processes for the current login session on Windows, or the the same as Self on Unix
Global All processes on the system, across every session

The following example will create a new global Mutex:

Start-PodeServer {
    New-PodeMutex -Name 'ExampleMutex' -Scope Global
}

Once created, you can use the Mutex in Use-PodeMutex, Enter-PodeMutex, and Exit-PodeMutex.

Using a Mutex

To use a Mutex after creating one you can use Use-PodeMutex to enter a Mutex; invoke a scriptblock; and then exit a Mutex to free it up for another process.

Below are 2 scripts for creating 2 Pode servers. Both create the same global Mutex, and then use te Mutex to invoke a scriptblock. In 1 server the scriptblock sleeps for 10 seconds, and in the other for 2 seconds. If you run both servers and call the first server's Route, and then the second, the second will block until the first finishes - even though they're in different servers/threads.

  • First server

    Start-PodeServer {
        Add-PodeEndpoint -Address localhost -Port 8080 -Protocol Http
    
        New-PodeMutex -Name 'GlobalMutex' -Scope Global
    
        Add-PodeRoute -Method Get -Path '/sleep' -ScriptBlock {
            Use-PodeMutex -Name 'GlobalMutex' -ScriptBlock {
                Start-Sleep -Seconds 10
            }
        }
    }
    

  • Second server

    Start-PodeServer {
        Add-PodeEndpoint -Address localhost -Port 8081 -Protocol Http
    
        New-PodeMutex -Name 'GlobalMutex' -Scope Global
    
        Add-PodeRoute -Method Get -Path '/sleep' -ScriptBlock {
            Use-PodeMutex -Name 'GlobalMutex' -ScriptBlock {
                Start-Sleep -Seconds 2
            }
        }
    }
    

Enter / Exit

You can have more advanced control over the using of Mutexes via Enter-PodeMutex and Exit-PodeMutex. Using these functions you can enter a Mutex, run some logic, and then exit the Mutex - but you don't have to do it all in the same function or scriptblock.

Enter-PodeMutex can be used to initially place enter a Mutex, and then you must call Exit-PodeMutex later on to exit the Mutex:

Start-PodeServer -Threads 2 {
    Add-PodeEndpoint -Address * -Port 8090 -Protocol Http

    New-PodeMutex -Name 'GlobalMutex' -Scope Global

    Add-PodeRoute -Method Get -Path '/sleep' -ScriptBlock {
        try {
            Enter-PodeMutex -Name 'GlobalMutex'
            Start-Sleep -Seconds 10
        }
        finally {
            Exit-PodeMutex -Name 'GlobalMutex'
        }
    }
}

Timeout

When using a Mutex by default Pode will wait indefinitely for the Mutex to be released before entering it. You can use the -Timeout parameter to specify a number of milliseconds to timeout after if a Mutex fails be released.

Start-PodeServer -Threads 2 {
    Add-PodeEndpoint -Address * -Port 8090 -Protocol Http

    New-PodeMutex -Name 'GlobalMutex' -Scope Global

    Add-PodeRoute -Method Get -Path '/sleep' -ScriptBlock {
        Use-PodeMutex -Name 'GlobalMutex' -Timeout 2000 -ScriptBlock {
            Start-Sleep -Seconds 2
        }
    }
}