72 Zeilen
1.5 KiB
Go
72 Zeilen
1.5 KiB
Go
|
package event
|
||
|
|
||
|
import (
|
||
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
// IPCMessage is a wrapper for a regular eventMessage with a destination (onion|AppDest) so the other side of the bridge can route appropriately
|
||
|
type IPCMessage struct {
|
||
|
Dest string
|
||
|
Message Event
|
||
|
}
|
||
|
|
||
|
type pipeBridge struct {
|
||
|
in chan IPCMessage
|
||
|
out chan IPCMessage
|
||
|
closedChan chan bool
|
||
|
closed bool
|
||
|
lock sync.Mutex
|
||
|
}
|
||
|
|
||
|
// IPCBridge is an interface to a IPC construct used to communicate IPCMessages
|
||
|
type IPCBridge interface {
|
||
|
Read() (IPCMessage, bool)
|
||
|
Write(message *IPCMessage)
|
||
|
Shutdown()
|
||
|
}
|
||
|
|
||
|
// MakePipeBridge returns a simple testing IPCBridge made from inprocess go channels
|
||
|
func MakePipeBridge() (b1, b2 IPCBridge) {
|
||
|
chan1 := make(chan IPCMessage)
|
||
|
chan2 := make(chan IPCMessage)
|
||
|
closed := make(chan bool)
|
||
|
|
||
|
a := &pipeBridge{in: chan1, out: chan2, closedChan: closed, closed: false}
|
||
|
b := &pipeBridge{in: chan2, out: chan1, closedChan: closed, closed: false}
|
||
|
|
||
|
go monitor(a, b)
|
||
|
|
||
|
return a, b
|
||
|
}
|
||
|
|
||
|
func monitor(a, b *pipeBridge) {
|
||
|
<-a.closedChan
|
||
|
a.closed = true
|
||
|
b.closed = true
|
||
|
a.closedChan <- true
|
||
|
}
|
||
|
|
||
|
func (pb *pipeBridge) Read() (message IPCMessage, ok bool) {
|
||
|
message, ok = <-pb.in
|
||
|
return
|
||
|
}
|
||
|
|
||
|
func (pb *pipeBridge) Write(message *IPCMessage) {
|
||
|
pb.lock.Lock()
|
||
|
defer pb.lock.Unlock()
|
||
|
log.Infof("pb.Write: %v\n", message)
|
||
|
if !pb.closed {
|
||
|
pb.out <- *message
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (pb *pipeBridge) Shutdown() {
|
||
|
if !pb.closed {
|
||
|
close(pb.in)
|
||
|
close(pb.out)
|
||
|
pb.closedChan <- true
|
||
|
<-pb.closedChan
|
||
|
}
|
||
|
}
|