|
| 1 | +// Shared Object Function Manager |
| 2 | +// Copyright (c) 2020 - 2021 Jaskirat Rajasansir |
| 3 | + |
| 4 | +.require.lib each `type`file`time`ns`os`env; |
| 5 | + |
| 6 | + |
| 7 | +/ The target namespace that all shared library functions will be loaded into |
| 8 | +.so.cfg.targetNs:`.so.libs; |
| 9 | + |
| 10 | + |
| 11 | +/ Store of all loaded shared library functions |
| 12 | +.so.loaded:`kdbRef xkey flip `kdbRef`soName`soPath`soFunctionName`loadTime!"SSSSP"$\:(); |
| 13 | + |
| 14 | + |
| 15 | +.so.init:{ |
| 16 | + .log.if.info "Shared object namespace [ Namespace: ",string[.so.cfg.targetNs]," ]"; |
| 17 | + set[.so.cfg.targetNs; 1#.q]; |
| 18 | + }; |
| 19 | + |
| 20 | + |
| 21 | +/ Attempts to find a shared object with the specified name within the paths specified by the source environment variable |
| 22 | +/ NOTE: If multiple files match the specified name, only the first will be returned |
| 23 | +/ @param soName (String|Symbol) The shared object name to search for, including suffix |
| 24 | +/ @returns (FilePath) Path to the matching shared object file, or empty symbol if no matching file found |
| 25 | +/ @see .os.sharedObjectEnvVar |
| 26 | +/ @see .env.get |
| 27 | +.so.findSharedObject:{[soName] |
| 28 | + soPaths:raze .file.findFilePaths["*",.type.ensureString soName;] each .env.get .os.sharedObjectEnvVar; |
| 29 | + |
| 30 | + if[0 = count soPaths; |
| 31 | + .log.if.warn "No matching paths found for shared object [ Shared Object: ",.type.ensureString[soName]," ] [ Source Env Var: ",string[.os.sharedObjectEnvVar]," ]"; |
| 32 | + :`; |
| 33 | + ]; |
| 34 | + |
| 35 | + if[1 < count soPaths; |
| 36 | + .log.if.warn "Multiple matching files for shared objects. Returning first [ Shared Object: ",.type.ensureString[soName]," ] [ Matching: ",string[count soPaths]," ]"; |
| 37 | + ]; |
| 38 | + |
| 39 | + :first soPaths; |
| 40 | + }; |
| 41 | + |
| 42 | +/ Loads the specified function from the specified shared object into the process |
| 43 | +/ NOTE: If the function is already loaded into the process, it will not be reloaded |
| 44 | +/ @param soName (Symbol|FilePath) The name of the shared object to find, or the specific shared object to load the function from |
| 45 | +/ @param soFunctionName (Symbol) The function to reference in the shared object |
| 46 | +/ @param soFunctionArgs (Long) The number of arguments the function in the shared object requires to execute |
| 47 | +/ @returns (Symbol) Namespace reference to the shared object code loaded into the current process |
| 48 | +/ @throws SharedObjectNotFoundException If the specified shared object is a name and a matching file could not be found |
| 49 | +/ @see .so.cfg.targetNs |
| 50 | +/ @see .so.findSharedObject |
| 51 | +.so.loadFunction:{[soName; soFunctionName; soFunctionArgs] |
| 52 | + if[not all .type.isSymbol each (soName; soFunctionName); |
| 53 | + '"InvalidArgumentException"; |
| 54 | + ]; |
| 55 | + |
| 56 | + if[not .type.isLong soFunctionArgs; |
| 57 | + '"InvalidArgumentException"; |
| 58 | + ]; |
| 59 | + |
| 60 | + soPath:soName; |
| 61 | + |
| 62 | + if[not .type.isFilePath soPath; |
| 63 | + soPath:.so.findSharedObject soName; |
| 64 | + ]; |
| 65 | + |
| 66 | + if[null soPath; |
| 67 | + '"SharedObjectNotFoundException"; |
| 68 | + ]; |
| 69 | + |
| 70 | + / Remove file suffix from shared object path for 2: |
| 71 | + soLoadPath:` sv @[` vs soPath; 1; first ` vs]; |
| 72 | + |
| 73 | + kdbFunctionName:` sv .so.cfg.targetNs,last[` vs soLoadPath],soFunctionName; |
| 74 | + |
| 75 | + if[.ns.isSet kdbFunctionName; |
| 76 | + .log.if.info "Shared object function already loaded [ Shared Object: ",string[soName]," ] [ Function: ",string[soFunctionName]," ]"; |
| 77 | + :kdbFunctionName; |
| 78 | + ]; |
| 79 | + |
| 80 | + .log.if.info "Loading function from shared object [ Shared Object: ",string[soName]," (",string[soPath],") ] [ Function: ",string[soFunctionName]," -> ",string[kdbFunctionName]," ] [ Args: ",string[soFunctionArgs]," ]"; |
| 81 | + |
| 82 | + set[kdbFunctionName;] soLoadPath 2: (soFunctionName; soFunctionArgs); |
| 83 | + |
| 84 | + .so.loaded[kdbFunctionName]:(soName; soPath; soFunctionName; .time.now[]); |
| 85 | + |
| 86 | + .log.if.info "Shared object function loaded OK [ Shared Object: ",string[soName]," ] [ Function: ",string[kdbFunctionName]," ]"; |
| 87 | + |
| 88 | + :kdbFunctionName; |
| 89 | + }; |
| 90 | + |
0 commit comments