Skip to content

Commit

Permalink
added thread type support to the function thread to allow spawning
Browse files Browse the repository at this point in the history
daemon or user threads
  • Loading branch information
jlangch committed Mar 29, 2024
1 parent 11a1042 commit 240d6b1
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ All notable changes to this project will be documented in this file.
### Added

- function `io/file-normalize-utf`
- thread type support to the function `thread` to allow spawning daemon or user
threads



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2541,20 +2541,29 @@ public VncVal apply(final VncList args) {
VncFunction
.meta()
.arglists(
"(thread f)", "(thread f name)")
"(thread f)",
"(thread f name)",
"(thread f name type)")
.doc(
"Executes the function f in another thread, returning immediately to the " +
"calling thread. Returns a `promise` which will receive the result of " +
"calling the function f when completed. Optionally a name can be assigned " +
"to the spawned thread." +
"\n\n" +
"The thread can be given a name by passing the *name* argument. By default " +
"the thread names is set to \"venice-thread\". For each thread spawned on " +
"a name the thread's name will be suffixed with an incrementing index starting " +
"from 1.\n\n" +
"The thread type *daemon* or *user* can be controlled by the *type* argument " +
"that must be one of {:daemon, :user}. By default a daemon thread is spawned.\n\n" +
"*Note:* Each call to `thread` creates a new expensive system thread. " +
"Consider to use futures or promises that use an *ExecutorService* to " +
"deal efficiently with threads.")
.examples(
"@(thread #(do (sleep 100) 1))",
"@(thread #(do (sleep 100) (thread-name)))",
"@(thread #(do (sleep 100) (thread-name)) \"job\")",
"@(thread #(do (sleep 100) (thread-name)) \"job\" :user)",
";; consumer / producer \n" +
"(do \n" +
" (defn produce [q] \n" +
Expand All @@ -2571,15 +2580,25 @@ public VncVal apply(final VncList args) {
) {
@Override
public VncVal apply(final VncList args) {
ArityExceptions.assertArity(this, args, 1, 2);
ArityExceptions.assertArity(this, args, 1, 2, 3);

final VncFunction fn = Coerce.toVncFunction(args.first());
fn.sandboxFunctionCallValidation();

final String name = args.size() == 2
final String name = args.size() >= 2
? Coerce.toVncString(args.second()).getValue()
: null;

final VncKeyword type = args.size() == 3
? Coerce.toVncKeyword(args.third())
: new VncKeyword("daemon");

if (!(type.hasValue("daemon") || type.hasValue("user"))) {
throw new VncException(String.format(
"Function 'thread' requires type to be one of {:daemon, :user}. %s is invalid",
type.getValue()));
}

final CallFrame[] cf = new CallFrame[] {
new CallFrame(this, args),
new CallFrame(fn) };
Expand All @@ -2601,6 +2620,7 @@ public VncVal apply(final VncList args) {


final Thread th = GlobalThreadFactory.newThread(name, taskWrapper);
th.setDaemon(type.hasValue("daemon"));
th.start();

return new VncJavaObject(result);
Expand Down

0 comments on commit 240d6b1

Please sign in to comment.