Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
f6d454b2
Commit
f6d454b2
authored
Jul 27, 2017
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow an ExceptionCallback to control how new threads' ExceptionCallbacks are initialized.
parent
67b9ea88
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
58 additions
and
1 deletion
+58
-1
exception.c++
c++/src/kj/exception.c++
+13
-0
exception.h
c++/src/kj/exception.h
+8
-0
thread-test.c++
c++/src/kj/thread-test.c++
+34
-0
thread.c++
c++/src/kj/thread.c++
+2
-1
thread.h
c++/src/kj/thread.h
+1
-0
No files found.
c++/src/kj/exception.c++
View file @
f6d454b2
...
...
@@ -24,6 +24,7 @@
#include "debug.h"
#include "threadlocal.h"
#include "miniposix.h"
#include "function.h"
#include <stdlib.h>
#include <exception>
#include <new>
...
...
@@ -649,6 +650,10 @@ ExceptionCallback::StackTraceMode ExceptionCallback::stackTraceMode() {
return
next
.
stackTraceMode
();
}
Function
<
void
(
Function
<
void
()
>
)
>
ExceptionCallback
::
getThreadInitializer
()
{
return
next
.
getThreadInitializer
();
}
class
ExceptionCallback
::
RootExceptionCallback
:
public
ExceptionCallback
{
public
:
RootExceptionCallback
()
:
ExceptionCallback
(
*
this
)
{}
...
...
@@ -703,6 +708,14 @@ public:
#endif
}
Function
<
void
(
Function
<
void
()
>
)
>
getThreadInitializer
()
override
{
return
[](
Function
<
void
()
>
func
)
{
// No initialization needed since RootExceptionCallback is automatically the root callback
// for new threads.
func
();
};
}
private
:
void
logException
(
LogSeverity
severity
,
Exception
&&
e
)
{
// We intentionally go back to the top exception callback on the stack because we don't want to
...
...
c++/src/kj/exception.h
View file @
f6d454b2
...
...
@@ -33,6 +33,7 @@
namespace
kj
{
class
ExceptionImpl
;
template
<
typename
T
>
class
Function
;
class
Exception
{
// Exception thrown in case of fatal errors.
...
...
@@ -216,6 +217,11 @@ public:
virtual
StackTraceMode
stackTraceMode
();
// Returns the current preferred stack trace mode.
virtual
Function
<
void
(
Function
<
void
()
>
)
>
getThreadInitializer
();
// Called just before a new thread is spawned using kj::Thread. Returns a function which should
// be invoked inside the new thread to initialize the thread's ExceptionCallback. The initializer
// function itself receives, as its parameter, the thread's main function, which it must call.
protected
:
ExceptionCallback
&
next
;
...
...
@@ -224,6 +230,8 @@ private:
class
RootExceptionCallback
;
friend
ExceptionCallback
&
getExceptionCallback
();
friend
class
Thread
;
};
ExceptionCallback
&
getExceptionCallback
();
...
...
c++/src/kj/thread-test.c++
View file @
f6d454b2
...
...
@@ -86,5 +86,39 @@ KJ_TEST("detaching thread doesn't delete function") {
}
}
class
CapturingExceptionCallback
final
:
public
ExceptionCallback
{
public
:
CapturingExceptionCallback
(
String
&
target
)
:
target
(
target
)
{}
void
logMessage
(
LogSeverity
severity
,
const
char
*
file
,
int
line
,
int
contextDepth
,
String
&&
text
)
{
target
=
kj
::
mv
(
text
);
}
private
:
String
&
target
;
};
class
ThreadedExceptionCallback
final
:
public
ExceptionCallback
{
public
:
Function
<
void
(
Function
<
void
()
>
)
>
getThreadInitializer
()
override
{
return
[
this
](
Function
<
void
()
>
func
)
{
CapturingExceptionCallback
context
(
captured
);
func
();
};
}
String
captured
;
};
KJ_TEST
(
"threads pick up exception callback initializer"
)
{
ThreadedExceptionCallback
context
;
KJ_EXPECT
(
context
.
captured
!=
"foobar"
);
Thread
([]()
{
KJ_LOG
(
ERROR
,
"foobar"
);
});
KJ_EXPECT
(
context
.
captured
==
"foobar"
,
context
.
captured
);
}
}
// namespace
}
// namespace kj
c++/src/kj/thread.c++
View file @
f6d454b2
...
...
@@ -112,6 +112,7 @@ void Thread::detach() {
Thread
::
ThreadState
::
ThreadState
(
Function
<
void
()
>
func
)
:
func
(
kj
::
mv
(
func
)),
initializer
(
getExceptionCallback
().
getThreadInitializer
()),
exception
(
nullptr
),
refcount
(
2
)
{}
...
...
@@ -138,7 +139,7 @@ void* Thread::runThread(void* ptr) {
#endif
ThreadState
*
state
=
reinterpret_cast
<
ThreadState
*>
(
ptr
);
KJ_IF_MAYBE
(
exception
,
kj
::
runCatchingExceptions
([
&
]()
{
state
->
func
(
);
state
->
initializer
(
kj
::
mv
(
state
->
func
)
);
}))
{
state
->
exception
=
kj
::
mv
(
*
exception
);
}
...
...
c++/src/kj/thread.h
View file @
f6d454b2
...
...
@@ -56,6 +56,7 @@ private:
ThreadState
(
Function
<
void
()
>
func
);
Function
<
void
()
>
func
;
Function
<
void
(
Function
<
void
()
>
)
>
initializer
;
kj
::
Maybe
<
kj
::
Exception
>
exception
;
unsigned
int
refcount
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment