Skip to content

Commit 3cfde52

Browse files
committed
Add new 'so' library - shared object function manager
1 parent 9e220a7 commit 3cfde52

File tree

2 files changed

+90
-1
lines changed

2 files changed

+90
-1
lines changed

src/env.q

-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
.env.cache[envVar]:envVal;
7070
};
7171

72-
7372
/ Parses a '$PATH'-type environment variable into a list of folder paths for use within kdb+
7473
/ NOTE: Only valid folders will be returned from this function
7574
/ @param rawPath (String) The environment variable output

src/so.q

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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

Comments
 (0)