Skip to content

Commit

Permalink
Add build tags to signal package (#1119)
Browse files Browse the repository at this point in the history
  • Loading branch information
divan authored Aug 7, 2018
1 parent 4b8c669 commit 27e432a
Show file tree
Hide file tree
Showing 8 changed files with 424 additions and 251 deletions.
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,32 +93,32 @@ statusgo-cross: statusgo-android statusgo-ios

statusgo-linux: xgo ##@cross-compile Build status-go for Linux
./_assets/patches/patcher -b . -p geth-xgo
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=linux/amd64 -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/statusd
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=linux/amd64 -v -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./cmd/statusd
./_assets/patches/patcher -b . -p geth-xgo -r
@echo "Android cross compilation done."

statusgo-android: xgo ##@cross-compile Build status-go for Android
./_assets/patches/patcher -b . -p geth-xgo
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=android-16/aar -v -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
./_assets/patches/patcher -b . -p geth-xgo -r
@echo "Android cross compilation done."

statusgo-ios: xgo ##@cross-compile Build status-go for iOS
./_assets/patches/patcher -b . -p geth-xgo
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
$(GOPATH)/bin/xgo --image $(XGOIMAGE) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
./_assets/patches/patcher -b . -p geth-xgo -r
@echo "iOS framework cross compilation done."

statusgo-ios-simulator: xgo ##@cross-compile Build status-go for iOS Simulator
@docker pull $(XGOIMAGEIOSSIM)
./_assets/patches/patcher -b . -p geth-xgo
$(GOPATH)/bin/xgo --image $(XGOIMAGEIOSSIM) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags '$(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
$(GOPATH)/bin/xgo --image $(XGOIMAGEIOSSIM) --go=$(GO) -out statusgo --dest=$(GOBIN) --targets=ios-9.3/framework -v -tags 'library $(BUILD_TAGS)' $(BUILD_FLAGS) ./lib
./_assets/patches/patcher -b . -p geth-xgo -r
@echo "iOS framework cross compilation done."

statusgo-library: ##@cross-compile Build status-go as static library for current platform
@echo "Building static library..."
go build -buildmode=c-archive -o $(GOBIN)/libstatus.a ./lib
go build -buildmode=c-archive -tags library -o $(GOBIN)/libstatus.a ./lib
@echo "Static library built:"
@ls -la $(GOBIN)/libstatus.*

Expand Down Expand Up @@ -193,7 +193,7 @@ test-unit: UNIT_TEST_PACKAGES = $(shell go list ./... | \
grep -v /t/benchmarks | \
grep -v /lib)
test-unit: ##@tests Run unit and integration tests
go test -v $(UNIT_TEST_PACKAGES) $(gotest_extraflags)
go test $(UNIT_TEST_PACKAGES) $(gotest_extraflags)

test-unit-race: gotest_extraflags=-race
test-unit-race: test-unit ##@tests Run unit and integration tests with -race flag
Expand Down
12 changes: 0 additions & 12 deletions signal/ios.go

This file was deleted.

207 changes: 1 addition & 206 deletions signal/signals.c
Original file line number Diff line number Diff line change
@@ -1,208 +1,5 @@
#if defined(IOS_DEPLOYMENT)
// ======================================================================================
// iOS framework compilation using xgo
// ======================================================================================

#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
#include <objc/objc.h>
#include <objc/runtime.h>
#include <objc/message.h>

static id statusServiceClassRef = nil;
static SEL statusServiceSelector = nil;

static bool initLibrary() {
if (statusServiceClassRef == nil) {
statusServiceClassRef = objc_getClass("Status");
if (statusServiceClassRef == nil) return false;
}

if (statusServiceSelector == nil) {
statusServiceSelector = sel_getUid("signalEvent:");
if (statusServiceSelector == nil) return false;
}

return true;
}


/*!
* @brief Calls static method signalEvent of class GethService.
*
* @param jsonEvent - UTF8 string
*
* @note Definition of signalEvent method.
* + (void)signalEvent:(const char *)json
*/
bool StatusServiceSignalEvent(const char *jsonEvent) {
if (!initLibrary()) return false;

void (*action)(id, SEL, const char *) = (void (*)(id, SEL, const char *)) objc_msgSend;
action(statusServiceClassRef, statusServiceSelector, jsonEvent);

return true;
}

void SetEventCallback(void *cb) {
}

#elif defined(ANDROID_DEPLOYMENT)
// ======================================================================================
// Android archive compilation using xgo
// ======================================================================================

#include <stddef.h>
#include <stdbool.h>
#include <jni.h>

bool StatusServiceSignalEvent(const char *jsonEvent);

static JavaVM *gJavaVM = NULL;
static jclass JavaClassPtr_StatusService = NULL;
static jmethodID JavaMethodPtr_signalEvent = NULL;

static bool JniLibraryInit(JNIEnv *env);

/*!
* @brief Get interface to JNI.
*
* @return true if thread should be detached from JNI.
*/
static bool JniAttach(JNIEnv **env) {
jint status;

if (gJavaVM == NULL) {
env = NULL;
}

status = (*gJavaVM)->GetEnv(gJavaVM, (void **)env, JNI_VERSION_1_6);
if (status == JNI_EDETACHED) {
// attach thread to JNI
//(*gJavaVM)->AttachCurrentThread( gJavaVM, (void **)env, NULL ); // Oracle JNI API
(*gJavaVM)->AttachCurrentThread(gJavaVM, env, NULL); // Android JNI API
return true;
} else if (status != JNI_OK) {
return false;
}

return false;
}

/*!
* @brief The VM calls JNI_OnLoad when the native library is loaded.
*/
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
bool detach;
JNIEnv *env;
int result = JNI_VERSION_1_6;

gJavaVM = vm;
// +build library,!android,!arm

// attach thread to JNI
detach = JniAttach(&env);
if (env == NULL) {
// failed
gJavaVM = NULL;
return 0;
}

if (!JniLibraryInit(env)) {
// fail loading of JNI library
result = 0;
}

if (detach) {
// detach thread from JNI
(*gJavaVM)->DetachCurrentThread(gJavaVM);
}

if (result != JNI_VERSION_1_6) {
gJavaVM = NULL;
}

return result;
}

/*!
* @brief Initialize library.
*/
bool JniLibraryInit(JNIEnv *env) {
int i;

JavaClassPtr_StatusService = (*env)->FindClass(env, "im/status/ethereum/module/StatusService");
if (JavaClassPtr_StatusService == NULL) return false;

JavaClassPtr_StatusService = (jclass)(*env)->NewGlobalRef(env, JavaClassPtr_StatusService);
if (JavaClassPtr_StatusService == NULL) return false;

struct {
bool bStatic;
jclass classPtr;
jmethodID *methodPtr;
const char *methodId;
const char *params;
} javaMethodDescriptors[] = {
{
true,
JavaClassPtr_StatusService,
&JavaMethodPtr_signalEvent, // &JavaMethodPtr_someNonStaticMethod
"signalEvent", // someNonStaticMethod
"(Ljava/lang/String;)V"
},
};

for (i = 0; i < sizeof(javaMethodDescriptors) / sizeof(javaMethodDescriptors[0]); i++) {
if (javaMethodDescriptors[i].bStatic) {
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetStaticMethodID(
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
} else {
*(javaMethodDescriptors[i].methodPtr) = (*env)->GetMethodID(
env, javaMethodDescriptors[i].classPtr, javaMethodDescriptors[i].methodId, javaMethodDescriptors[i].params);
}

if (*(javaMethodDescriptors[i].methodPtr) == NULL) return false;
}

return true;
}

/*!
* @brief Calls static method signalEvent of class im.status.ethereum.module.StatusService.
*
* @param jsonEvent - UTF8 string
*/
bool StatusServiceSignalEvent(const char *jsonEvent) {
bool detach;
JNIEnv *env;

// attach thread to JNI
detach = JniAttach( &env );
if (env == NULL) { // failed
return false;
}

jstring javaJsonEvent = NULL;
if (jsonEvent != NULL) {
javaJsonEvent = (*env)->NewStringUTF(env, jsonEvent);
}

(*env)->CallStaticVoidMethod(env, JavaClassPtr_StatusService, JavaMethodPtr_signalEvent, javaJsonEvent);

if (javaJsonEvent != NULL) (*env)->DeleteLocalRef(env, javaJsonEvent);

if (detach) { // detach thread from JNI
(*gJavaVM)->DetachCurrentThread(gJavaVM);
}

return true;
}

void SetEventCallback(void *cb) {
}

#else
// ======================================================================================
// cgo compilation (for desktop platforms and local tests)
// ======================================================================================
Expand All @@ -228,5 +25,3 @@ bool StatusServiceSignalEvent(const char *jsonEvent) {
void SetEventCallback(void *cb) {
gCallback = (callback)cb;
}

#endif
38 changes: 11 additions & 27 deletions signal/signals.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
// +build !library

package signal

/*
#include <stddef.h>
#include <stdbool.h>
#include <stdlib.h>
extern bool StatusServiceSignalEvent(const char *jsonEvent);
extern void SetEventCallback(void *cb);
*/
import "C"
import (
"encoding/json"

"unsafe"

"sync"
Expand Down Expand Up @@ -44,9 +37,9 @@ func send(typ string, event interface{}) {
return
}

str := C.CString(string(data))
C.StatusServiceSignalEvent(str)
C.free(unsafe.Pointer(str))
notificationHandlerMutex.RLock()
notificationHandler(string(data))
notificationHandlerMutex.RUnlock()
}

// NodeNotificationHandler defines a handler able to process incoming node events.
Expand All @@ -60,6 +53,7 @@ var notificationHandlerMutex sync.RWMutex

// SetDefaultNodeNotificationHandler sets notification handler to invoke on Send
func SetDefaultNodeNotificationHandler(fn NodeNotificationHandler) {
logger.Warn("[DEBUG] Overriding notification handler")
notificationHandlerMutex.Lock()
notificationHandler = fn
notificationHandlerMutex.Unlock()
Expand All @@ -77,23 +71,13 @@ func TriggerDefaultNodeNotificationHandler(jsonEvent string) {
logger.Trace("Notification received", "event", jsonEvent)
}

//export NotifyNode
//nolint: golint
func NotifyNode(jsonEvent *C.char) {
func TriggerTestSignal() {
str := `{"answer": 42}`
notificationHandlerMutex.RLock()
defer notificationHandlerMutex.RUnlock()
notificationHandler(C.GoString(jsonEvent))
notificationHandler(str)
notificationHandlerMutex.RUnlock()
}

//export TriggerTestSignal
//nolint: golint
func TriggerTestSignal() {
str := C.CString(`{"answer": 42}`)
C.StatusServiceSignalEvent(str)
C.free(unsafe.Pointer(str))
}

// SetSignalEventCallback set callback
func SetSignalEventCallback(cb unsafe.Pointer) {
C.SetEventCallback(cb)
}
func SetSignalEventCallback(cb unsafe.Pointer) {}
Loading

0 comments on commit 27e432a

Please sign in to comment.