diff options
Diffstat (limited to 'extras/gomemif/memif')
-rw-r--r-- | extras/gomemif/memif/control_channel.go | 41 | ||||
-rw-r--r-- | extras/gomemif/memif/interface.go | 26 |
2 files changed, 62 insertions, 5 deletions
diff --git a/extras/gomemif/memif/control_channel.go b/extras/gomemif/memif/control_channel.go index 12672e6e2f8..4788fcb5ea5 100644 --- a/extras/gomemif/memif/control_channel.go +++ b/extras/gomemif/memif/control_channel.go @@ -67,11 +67,22 @@ type Socket struct { interfaceList *list.List ccList *list.List epfd int + interruptfd int wakeEvent syscall.EpollEvent stopPollChan chan struct{} wg sync.WaitGroup } +type interrupt struct { + socket *Socket + event syscall.EpollEvent +} + +type memifInterrupt struct { + connection *Socket + qid uint16 +} + // StopPolling stops polling events on the socket func (socket *Socket) StopPolling() error { if socket.stopPollChan != nil { @@ -220,6 +231,15 @@ func (socket *Socket) handleEvent(event *syscall.EpollEvent) error { if socket.listener != nil && socket.listener.event.Fd == event.Fd { return socket.listener.handleEvent(event) } + intf := socket.interfaceList.Back().Value.(*Interface) + if intf.args.InterruptFunc != nil { + if int(event.Fd) == int(intf.args.InterruptFd) { + b := make([]byte, 8) + syscall.Read(int(event.Fd), b) + intf.onInterrupt(intf) + return nil + } + } for elt := socket.ccList.Front(); elt != nil; elt = elt.Next() { cc, ok := elt.Value.(*controlChannel) @@ -233,6 +253,25 @@ func (socket *Socket) handleEvent(event *syscall.EpollEvent) error { return fmt.Errorf(errorFdNotFound) } +func (socket *Socket) addInterrupt(fd int) (err error) { + l := &interrupt{ + // we will need this to look up master interface by id + socket: socket, + } + + l.event = syscall.EpollEvent{ + Events: syscall.EPOLLIN, + Fd: int32(fd), + } + err = socket.addEvent(&l.event) + if err != nil { + return fmt.Errorf("Failed to add event: ", err) + } + + return nil + +} + // handleEvent handles epoll event for listener func (l *listener) handleEvent(event *syscall.EpollEvent) error { // hang up @@ -725,7 +764,6 @@ func (cc *controlChannel) parseConnect() (err error) { if err != nil { return err } - cc.isConnected = true return nil @@ -764,7 +802,6 @@ func (cc *controlChannel) parseConnected() (err error) { if err != nil { return err } - cc.isConnected = true return nil diff --git a/extras/gomemif/memif/interface.go b/extras/gomemif/memif/interface.go index 15a8e87453c..4a45075ea4f 100644 --- a/extras/gomemif/memif/interface.go +++ b/extras/gomemif/memif/interface.go @@ -60,6 +60,8 @@ type ConnectedFunc func(i *Interface) error // DisconnectedFunc is a callback called when an interface is disconnected type DisconnectedFunc func(i *Interface) error +type InterruptFunc func(i *Interface) error + // MemoryConfig represents shared memory configuration type MemoryConfig struct { NumQueuePairs uint16 // number of queue pairs @@ -77,7 +79,9 @@ type Arguments struct { MemoryConfig MemoryConfig ConnectedFunc ConnectedFunc // callback called when interface changes status to connected DisconnectedFunc DisconnectedFunc // callback called when interface changes status to disconnected - PrivateData interface{} // private data used by client program + InterruptFunc InterruptFunc + PrivateData interface{} // private data used by client program + InterruptFd uint16 } // memoryRegion represents a shared memory mapped file @@ -110,6 +114,7 @@ type Interface struct { regions []memoryRegion txQueues []Queue rxQueues []Queue + onInterrupt InterruptFunc } // IsMaster returns true if the interfaces role is master, else returns false @@ -270,6 +275,10 @@ func RoleToString(isMaster bool) string { return "Slave" } +func memifPathIsAbstract(filename string) bool { + return (filename[0] == '@') +} + // RequestConnection is used by slave interface to connect to a socket and // create a control channel func (i *Interface) RequestConnection() error { @@ -283,6 +292,9 @@ func (i *Interface) RequestConnection() error { } usa := &syscall.SockaddrUnix{Name: i.socket.filename} + if memifPathIsAbstract(i.socket.GetFilename()) { + usa.Name = "\000" + usa.Name[1:] + } // Connect to listener socket err = syscall.Connect(fd, usa) if err != nil { @@ -315,7 +327,8 @@ func (socket *Socket) NewInterface(args *Arguments) (*Interface, error) { // copy interface configuration i := Interface{ - args: *args, + args: *args, + onInterrupt: args.InterruptFunc, } // set default values if i.args.MemoryConfig.NumQueuePairs == 0 { @@ -434,6 +447,7 @@ func (i *Interface) initializeQueues() (err error) { if err != nil { return err } + i.socket.addInterrupt(q.interruptFd) q.putRing() i.txQueues = append(i.txQueues, *q) @@ -452,11 +466,17 @@ func (i *Interface) initializeQueues() (err error) { i: i, } q.ring.setCookie(cookie) - q.ring.setFlags(1) + if i.args.InterruptFunc == nil { + q.ring.setFlags(1) + } else { + q.ring.setFlags(0) + } q.interruptFd, err = eventFd() if err != nil { return err } + i.args.InterruptFd = uint16(q.interruptFd) + i.socket.addInterrupt(q.interruptFd) q.putRing() i.rxQueues = append(i.rxQueues, *q) |