chore: merge probe-engine into probe-cli (#201)
This is how I did it: 1. `git clone https://github.com/ooni/probe-engine internal/engine` 2. ``` (cd internal/engine && git describe --tags) v0.23.0 ``` 3. `nvim go.mod` (merging `go.mod` with `internal/engine/go.mod` 4. `rm -rf internal/.git internal/engine/go.{mod,sum}` 5. `git add internal/engine` 6. `find . -type f -name \*.go -exec sed -i 's@/ooni/probe-engine@/ooni/probe-cli/v3/internal/engine@g' {} \;` 7. `go build ./...` (passes) 8. `go test -race ./...` (temporary failure on RiseupVPN) 9. `go mod tidy` 10. this commit message Once this piece of work is done, we can build a new version of `ooniprobe` that is using `internal/engine` directly. We need to do more work to ensure all the other functionality in `probe-engine` (e.g. making mobile packages) are still WAI. Part of https://github.com/ooni/probe/issues/1335
This commit is contained in:
parent
b1ce300c8d
commit
d57c78bc71
535 changed files with 66182 additions and 23 deletions
152
internal/engine/libooniffi/ooniffi.go
Normal file
152
internal/engine/libooniffi/ooniffi.go
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
//#include "ooniffi.h"
|
||||
//
|
||||
//#include <stdint.h>
|
||||
//#include <stdlib.h>
|
||||
//
|
||||
//struct ooniffi_task_ {
|
||||
// int64_t Handle;
|
||||
//};
|
||||
//
|
||||
// struct ooniffi_event_ {
|
||||
// char *String;
|
||||
//};
|
||||
"C"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/engine/oonimkall"
|
||||
)
|
||||
|
||||
var (
|
||||
idx C.int64_t
|
||||
m = make(map[C.int64_t]*oonimkall.Task)
|
||||
mu sync.Mutex
|
||||
)
|
||||
|
||||
func cstring(s string) *C.char {
|
||||
return C.CString(s)
|
||||
}
|
||||
|
||||
func freestring(s *C.char) {
|
||||
C.free(unsafe.Pointer(s))
|
||||
}
|
||||
|
||||
func gostring(s *C.char) string {
|
||||
return C.GoString(s)
|
||||
}
|
||||
|
||||
const maxIdx = C.INT64_MAX
|
||||
|
||||
//export ooniffi_task_start_
|
||||
func ooniffi_task_start_(settings *C.char) *C.ooniffi_task_t {
|
||||
if settings == nil {
|
||||
return nil
|
||||
}
|
||||
tp, err := oonimkall.StartTask(gostring(settings))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
// TODO(bassosimone): the following if is basic protection against
|
||||
// undefined behaviour, i.e., the counter wrapping around. A much
|
||||
// better strategy would probably be to restart from 0. However it's
|
||||
// also unclear if any device could run that many tests, so...
|
||||
if idx >= maxIdx {
|
||||
return nil
|
||||
}
|
||||
handle := idx
|
||||
idx++
|
||||
m[handle] = tp
|
||||
task := (*C.ooniffi_task_t)(C.malloc(C.sizeof_ooniffi_task_t))
|
||||
task.Handle = handle
|
||||
return task
|
||||
}
|
||||
|
||||
func setmaxidx() C.int64_t {
|
||||
o := idx
|
||||
idx = maxIdx
|
||||
return o
|
||||
}
|
||||
|
||||
func restoreidx(v C.int64_t) {
|
||||
idx = v
|
||||
}
|
||||
|
||||
//export ooniffi_task_wait_for_next_event
|
||||
func ooniffi_task_wait_for_next_event(task *C.ooniffi_task_t) (event *C.ooniffi_event_t) {
|
||||
if task != nil {
|
||||
mu.Lock()
|
||||
tp := m[task.Handle]
|
||||
mu.Unlock()
|
||||
if tp != nil {
|
||||
event = (*C.ooniffi_event_t)(C.malloc(C.sizeof_ooniffi_event_t))
|
||||
event.String = cstring(tp.WaitForNextEvent())
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//export ooniffi_task_is_done
|
||||
func ooniffi_task_is_done(task *C.ooniffi_task_t) C.int {
|
||||
var isdone C.int = 1
|
||||
if task != nil {
|
||||
mu.Lock()
|
||||
if tp := m[task.Handle]; tp != nil && !tp.IsDone() {
|
||||
isdone = 0
|
||||
}
|
||||
mu.Unlock()
|
||||
}
|
||||
return isdone
|
||||
}
|
||||
|
||||
//export ooniffi_task_interrupt
|
||||
func ooniffi_task_interrupt(task *C.ooniffi_task_t) {
|
||||
if task != nil {
|
||||
mu.Lock()
|
||||
if tp := m[task.Handle]; tp != nil {
|
||||
tp.Interrupt()
|
||||
}
|
||||
mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
//export ooniffi_event_serialization_
|
||||
func ooniffi_event_serialization_(event *C.ooniffi_event_t) (s *C.char) {
|
||||
if event != nil {
|
||||
s = event.String
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//export ooniffi_event_destroy
|
||||
func ooniffi_event_destroy(event *C.ooniffi_event_t) {
|
||||
if event != nil {
|
||||
C.free(unsafe.Pointer(event.String))
|
||||
C.free(unsafe.Pointer(event))
|
||||
}
|
||||
}
|
||||
|
||||
//export ooniffi_task_destroy
|
||||
func ooniffi_task_destroy(task *C.ooniffi_task_t) {
|
||||
if task != nil {
|
||||
mu.Lock()
|
||||
tp := m[task.Handle]
|
||||
delete(m, task.Handle)
|
||||
mu.Unlock()
|
||||
C.free(unsafe.Pointer(task))
|
||||
if tp != nil { // drain task if needed
|
||||
tp.Interrupt()
|
||||
go func() {
|
||||
for !tp.IsDone() {
|
||||
tp.WaitForNextEvent()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {}
|
||||
Loading…
Reference in a new issue