|
| 1 | +// Package binderprocess provides access to ABinderProcess_* functions |
| 2 | +// that are not part of the public NDK headers but available at runtime |
| 3 | +// via dlsym in libbinder_ndk.so. |
| 4 | +package binderprocess |
| 5 | + |
| 6 | +/* |
| 7 | +#include <dlfcn.h> |
| 8 | +#include <stdint.h> |
| 9 | +
|
| 10 | +static int thread_pool_start(unsigned thread_pool_size) |
| 11 | +{ |
| 12 | + typedef int (*set_thread_pool_max_fn)(uint32_t); |
| 13 | + typedef void (*start_thread_pool_fn)(void); |
| 14 | +
|
| 15 | + void *h = dlopen("libbinder_ndk.so", RTLD_NOW | RTLD_LOCAL); |
| 16 | + if (h == NULL) |
| 17 | + return 1; |
| 18 | +
|
| 19 | + start_thread_pool_fn start_thread_pool = |
| 20 | + (start_thread_pool_fn)dlsym(h, "ABinderProcess_startThreadPool"); |
| 21 | + if (start_thread_pool == NULL) |
| 22 | + return 2; |
| 23 | +
|
| 24 | + if (thread_pool_size != 0) { |
| 25 | + set_thread_pool_max_fn set_thread_pool_max = |
| 26 | + (set_thread_pool_max_fn)dlsym(h, "ABinderProcess_setThreadPoolMaxThreadCount"); |
| 27 | + if (set_thread_pool_max == NULL) |
| 28 | + return 3; |
| 29 | + set_thread_pool_max(thread_pool_size); |
| 30 | + } |
| 31 | +
|
| 32 | + start_thread_pool(); |
| 33 | + return 0; |
| 34 | +} |
| 35 | +*/ |
| 36 | +import "C" |
| 37 | + |
| 38 | +import "fmt" |
| 39 | + |
| 40 | +// ErrDLOpenLibbinderNDK is returned when libbinder_ndk.so cannot be loaded. |
| 41 | +type ErrDLOpenLibbinderNDK struct{} |
| 42 | + |
| 43 | +func (ErrDLOpenLibbinderNDK) Error() string { |
| 44 | + return "unable to dlopen libbinder_ndk.so" |
| 45 | +} |
| 46 | + |
| 47 | +// ErrSymbolStartThreadPool is returned when ABinderProcess_startThreadPool is not found. |
| 48 | +type ErrSymbolStartThreadPool struct{} |
| 49 | + |
| 50 | +func (ErrSymbolStartThreadPool) Error() string { |
| 51 | + return "unable to find ABinderProcess_startThreadPool symbol" |
| 52 | +} |
| 53 | + |
| 54 | +// ErrSymbolSetThreadPoolMax is returned when ABinderProcess_setThreadPoolMaxThreadCount is not found. |
| 55 | +type ErrSymbolSetThreadPoolMax struct{} |
| 56 | + |
| 57 | +func (ErrSymbolSetThreadPoolMax) Error() string { |
| 58 | + return "unable to find ABinderProcess_setThreadPoolMaxThreadCount symbol" |
| 59 | +} |
| 60 | + |
| 61 | +// StartThreadPool starts the binder thread pool with the given number of threads. |
| 62 | +// If threads is 0, the default thread count is used (only startThreadPool is called). |
| 63 | +func StartThreadPool(threads int) error { |
| 64 | + rc := C.thread_pool_start(C.uint(threads)) |
| 65 | + switch rc { |
| 66 | + case 0: |
| 67 | + return nil |
| 68 | + case 1: |
| 69 | + return ErrDLOpenLibbinderNDK{} |
| 70 | + case 2: |
| 71 | + return ErrSymbolStartThreadPool{} |
| 72 | + case 3: |
| 73 | + return ErrSymbolSetThreadPoolMax{} |
| 74 | + default: |
| 75 | + return fmt.Errorf("thread_pool_start returned unexpected code %d", rc) |
| 76 | + } |
| 77 | +} |
0 commit comments