Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
ThreadingErrorFormatter.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Common/ResultErrorFormatter.h"
5#include "ThreadingError.h"
6
7namespace SC
8{
11
12namespace detail
13{
14inline ResultErrorFormat formatThreadingErrorWithContext(ThreadingError error, ThreadingErrorDetail errorDetail,
15 uint32_t nativeError, Span<char> output)
16{
17 ResultErrorFormatter formatter(output);
18 switch (error)
19 {
20 case ThreadingError::InvalidThreadFunction: formatter.append("Thread function is not valid"); break;
21 case ThreadingError::ThreadAlreadyStarted: formatter.append("Thread has already been started"); break;
22 case ThreadingError::ThreadNotStarted: formatter.append("Thread has not been started"); break;
23 case ThreadingError::ThreadCreationFailed: formatter.append("Failed to create thread"); break;
24 case ThreadingError::ThreadJoinFailed: formatter.append("Failed to join thread"); break;
25 case ThreadingError::ThreadDetachFailed: formatter.append("Failed to detach thread"); break;
26 case ThreadingError::ThreadPoolAlreadyCreated: formatter.append("Thread pool has already been created"); break;
27 case ThreadingError::InvalidWorkerThreadCount:
28 formatter.append("Worker thread count must be greater than zero");
29 break;
30 case ThreadingError::ThreadPoolNotCreated: formatter.append("Thread pool has not been created"); break;
31 case ThreadingError::TaskAlreadyQueued: formatter.append("Task has already been queued in this thread pool"); break;
32 case ThreadingError::TaskInUseByAnotherThreadPool: formatter.append("Task is in use by another thread pool"); break;
33 case ThreadingError::ThreadPoolThreadCreationFailed: formatter.append("Failed to create thread pool worker"); break;
34 default: return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
35 }
36
37 if (errorDetail != ThreadingErrorDetail::None)
38 {
39 formatter.append(" (detail: ");
40 switch (errorDetail)
41 {
42 case ThreadingErrorDetail::PosixPthreadCreate: formatter.append("POSIX create thread"); break;
43 case ThreadingErrorDetail::PosixPthreadJoin: formatter.append("POSIX join thread"); break;
44 case ThreadingErrorDetail::PosixPthreadDetach: formatter.append("POSIX detach thread"); break;
45 case ThreadingErrorDetail::WindowsCreateThread: formatter.append("Windows create thread"); break;
46 case ThreadingErrorDetail::WindowsWaitForSingleObject: formatter.append("Windows wait for thread"); break;
47 case ThreadingErrorDetail::WindowsCloseHandle: formatter.append("Windows close thread handle"); break;
48 default: return ResultErrorFormatter::failure(ResultErrorFormatStatus::UnknownError, output);
49 }
50 if (nativeError != 0)
51 {
52 formatter.append(", native error: ");
53 formatter.append(static_cast<uint64_t>(nativeError));
54 }
55 formatter.append(")");
56 }
57 else if (nativeError != 0 and
58 (error == ThreadingError::ThreadCreationFailed or error == ThreadingError::ThreadJoinFailed or
59 error == ThreadingError::ThreadDetachFailed or error == ThreadingError::ThreadPoolThreadCreationFailed))
60 {
61 formatter.append(" (native error: ");
62 formatter.append(static_cast<uint64_t>(nativeError));
63 formatter.append(")");
64 }
65 return formatter.finish();
66}
67} // namespace detail
68
72inline ResultErrorFormat formatThreadingError(ThreadingError error, Span<char> output)
73{
74 return detail::formatThreadingErrorWithContext(error, ThreadingErrorDetail::None, 0, output);
75}
76
78inline ResultErrorFormat formatThreadingError(Result result, Span<char> output)
79{
80 if (result)
81 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
82 if (result.category() != ThreadingResultCategory)
83 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
84 return formatThreadingError(static_cast<ThreadingError>(result.errorValue()), output);
85}
86
88inline ResultErrorFormat formatThreadingError(ResultThreading result, Span<char> output)
89{
90 if (result)
91 return ResultErrorFormatter::failure(ResultErrorFormatStatus::NotAnError, output);
92 if (result.result.category() != ThreadingResultCategory)
93 return ResultErrorFormatter::failure(ResultErrorFormatStatus::ForeignCategory, output);
94 return detail::formatThreadingErrorWithContext(static_cast<ThreadingError>(result.result.errorValue()),
95 result.detail, result.nativeError, output);
96}
97
99} // namespace SC
ResultErrorFormat formatThreadingError(ThreadingError error, Span< char > output)
Formats a canonical English Threading diagnostic into caller-owned storage.
Definition ThreadingErrorFormatter.h:72
ThreadingErrorDetail
Stable detail identifying the native/backend stage of a Threading failure.
Definition ThreadingError.h:31
ThreadingError
Stable error codes returned by the Threading library.
Definition ThreadingError.h:14
Threading result retaining optional native and backend-stage details.
Definition ThreadingError.h:49