X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=adapter%2Fvppapiclient%2Fvppapiclient_adapter.go;h=e9948e8f2bc3b4daef8f6682aa86cfd520ab31e7;hb=392a56b700fa6715d091e56c49f79bfe32613fc6;hp=82c820e3818ab59ea49ecd3542c0522a7f509844;hpb=96c3dce9de1aded53c1e4bf098817fc59692eb64;p=govpp.git diff --git a/adapter/vppapiclient/vppapiclient_adapter.go b/adapter/vppapiclient/vppapiclient_adapter.go index 82c820e..e9948e8 100644 --- a/adapter/vppapiclient/vppapiclient_adapter.go +++ b/adapter/vppapiclient/vppapiclient_adapter.go @@ -77,12 +77,22 @@ govpp_get_msg_index(char *name_and_crc) import "C" import ( - "errors" "fmt" + "os" "reflect" "unsafe" - "gerrit.fd.io/r/govpp.git/adapter" + "git.fd.io/govpp.git/adapter" + "github.com/fsnotify/fsnotify" +) + +const ( + // watchedFolder is a folder where vpp's shared memory is supposed to be created. + // File system events are monitored in this folder. + watchedFolder = "/dev/shm/" + // watchedFile is a name of the file in the watchedFolder. Once the file is present + // the vpp is ready to accept a new connection. + watchedFile = watchedFolder + "vpe-api" ) // vppAPIClientAdapter is the opaque context of the adapter. @@ -114,12 +124,12 @@ func (a *vppAPIClientAdapter) Disconnect() { // GetMsgID returns a runtime message ID for the given message name and CRC. func (a *vppAPIClientAdapter) GetMsgID(msgName string, msgCrc string) (uint16, error) { - nameAndCrc := C.CString(fmt.Sprintf("%s_%s", msgName, msgCrc)) + nameAndCrc := C.CString(msgName + "_" + msgCrc) defer C.free(unsafe.Pointer(nameAndCrc)) msgID := uint16(C.govpp_get_msg_index(nameAndCrc)) if msgID == ^uint16(0) { - return msgID, errors.New("unkonwn message") + return msgID, fmt.Errorf("unknown message: %v (crc: %v)", msgName, msgCrc) } return msgID, nil @@ -139,6 +149,42 @@ func (a *vppAPIClientAdapter) SetMsgCallback(cb func(context uint32, msgID uint1 a.callback = cb } +// WaitReady blocks until shared memory for sending +// binary api calls is present on the file system. +func (a *vppAPIClientAdapter) WaitReady() error { + watcher, err := fsnotify.NewWatcher() + if err != nil { + return err + } + defer watcher.Close() + + err = watcher.Add(watchedFolder) + if err != nil { + return err + } + + if fileExists(watchedFile) { + return nil + } + + for { + ev := <-watcher.Events + if ev.Name == watchedFile && (ev.Op&fsnotify.Create) == fsnotify.Create { + break + } + } + return nil +} + +func fileExists(name string) bool { + if _, err := os.Stat(name); err != nil { + if os.IsNotExist(err) { + return false + } + } + return true +} + //export go_msg_callback func go_msg_callback(msgID C.uint16_t, context C.uint32_t, data unsafe.Pointer, size C.size_t) { // convert unsafe.Pointer to byte slice