mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00

This largely copies over Spicy's `.clang-format` configuration file. The one place where we deviate is header include order since Zeek depends on headers being included in a certain order.
217 lines
6.2 KiB
C++
217 lines
6.2 KiB
C++
|
|
#pragma once
|
|
|
|
#include "zeek/zeek-config.h"
|
|
|
|
#include <unistd.h>
|
|
#include <atomic>
|
|
#include <cstdint>
|
|
#include <iosfwd>
|
|
#include <thread>
|
|
|
|
namespace zeek::threading {
|
|
|
|
class Manager;
|
|
|
|
/**
|
|
* Base class for all threads.
|
|
*
|
|
* This class encapsulates all the OS-level thread handling. All thread
|
|
* instances are automatically added to the threading::Manager for management. The
|
|
* manager also takes care of deleting them (which must not be done
|
|
* manually).
|
|
*/
|
|
class BasicThread {
|
|
public:
|
|
/**
|
|
* Creates a new thread object. Instantiating the object does however
|
|
* not yet start the actual OS thread, that requires calling Start().
|
|
*
|
|
* Only Zeek's main thread may create new thread instances.
|
|
*
|
|
* @param name A descriptive name for thread the thread. This may
|
|
* show up in messages to the user.
|
|
*/
|
|
BasicThread();
|
|
|
|
BasicThread(BasicThread const&) = delete;
|
|
BasicThread& operator=(BasicThread const&) = delete;
|
|
|
|
/**
|
|
* Returns a descriptive name for the thread. If not set via
|
|
* SetName(), a default name is chosen automatically.
|
|
*
|
|
* This method is safe to call from any thread.
|
|
*/
|
|
const char* Name() const { return name; }
|
|
|
|
/**
|
|
* Sets a descriptive name for the thread. This should be a string
|
|
* that's useful in output presented to the user and uniquely
|
|
* identifies the thread.
|
|
*
|
|
* This method must be called only from main thread at initialization
|
|
* time.
|
|
*/
|
|
void SetName(const char* name);
|
|
|
|
/**
|
|
* Set the name shown by the OS as the thread's description. Not
|
|
* supported on all OSs.
|
|
*
|
|
* Must be called only from the child thread.
|
|
*/
|
|
void SetOSName(const char* name);
|
|
|
|
/**
|
|
* Starts the thread. Calling this methods will spawn a new OS thread
|
|
* executing Run(). Note that one can't restart a thread after a
|
|
* Stop(), doing so will be ignored.
|
|
*
|
|
* Only Zeek's main thread must call this method.
|
|
*/
|
|
void Start();
|
|
|
|
/**
|
|
* Signals the thread to prepare for stopping, but doesn't block to
|
|
* wait for that to happen. Use WaitForStop() for that.
|
|
*
|
|
* The method lets Terminating() now return true, it does however not
|
|
* force the thread to terminate. It's up to the Run() method to to
|
|
* query Terminating() and exit eventually.
|
|
*
|
|
* Calling this method has no effect if Start() hasn't been executed
|
|
* yet.
|
|
*
|
|
* Only Zeek's main thread must call this method.
|
|
*/
|
|
void SignalStop();
|
|
|
|
/**
|
|
* Waits until a thread has stopped after receiving SignalStop().
|
|
*
|
|
* Calling this method has no effect if Start() hasn't been executed
|
|
* yet. If this is executed without calling SignalStop() first,
|
|
* results are undefined.
|
|
*
|
|
* Only Zeek's main thread must call this method.
|
|
*/
|
|
void WaitForStop();
|
|
|
|
/**
|
|
* Returns true if WaitForStop() has been called and finished.
|
|
*
|
|
* This method is safe to call from any thread.
|
|
*/
|
|
bool Terminating() const { return terminating; }
|
|
|
|
/**
|
|
* Returns true if Kill() has been called.
|
|
*
|
|
* This method is safe to call from any thread.
|
|
*/
|
|
bool Killed() const { return killed; }
|
|
|
|
/**
|
|
* A version of zeek::util::fmt() that the thread can safely use.
|
|
*
|
|
* This is safe to call from Run() but must not be used from any
|
|
* other thread than the current one.
|
|
*/
|
|
const char* Fmt(const char* format, ...) __attribute__((format(printf, 2, 3)));
|
|
;
|
|
|
|
/**
|
|
* A version of strerror() that the thread can safely use. This is
|
|
* essentially a wrapper around strerror_r(). Note that it keeps a
|
|
* single buffer per thread internally so the result remains valid
|
|
* only until the next call.
|
|
*/
|
|
const char* Strerror(int err);
|
|
|
|
protected:
|
|
friend class Manager;
|
|
|
|
/**
|
|
* Entry point for the thread. This must be overridden by derived
|
|
* classes and will execute in a separate thread once Start() is
|
|
* called. The thread will not terminate before this method finishes.
|
|
* An implementation should regularly check Terminating() to see if
|
|
* exiting has been requested.
|
|
*/
|
|
virtual void Run() = 0;
|
|
|
|
/**
|
|
* Executed with Start(). This is a hook into starting the thread. It
|
|
* will be called from Zeek's main thread after the OS thread has been
|
|
* started.
|
|
*/
|
|
virtual void OnStart() {}
|
|
|
|
/**
|
|
* Executed with SignalStop(). This is a hook into preparing the
|
|
* thread for stopping. It will be called from Zeek's main thread
|
|
* before the thread has been signaled to stop.
|
|
*/
|
|
virtual void OnSignalStop() {}
|
|
|
|
/**
|
|
* Executed with WaitForStop(). This is a hook into waiting for the
|
|
* thread to stop. It must be overridden by derived classes and only
|
|
* return once the thread has indeed finished processing. The method
|
|
* will be called from Zeek's main thread.
|
|
*/
|
|
virtual void OnWaitForStop() = 0;
|
|
|
|
/**
|
|
* Executed with Kill(). This is a hook into killing the thread.
|
|
*/
|
|
virtual void OnKill() {}
|
|
|
|
/**
|
|
* Destructor. This will be called by the manager.
|
|
*
|
|
* Only Zeek's main thread may delete thread instances.
|
|
*
|
|
*/
|
|
virtual ~BasicThread();
|
|
|
|
/**
|
|
* Waits until the thread's Run() method has finished and then joins
|
|
* it. This is called from the threading::Manager.
|
|
*/
|
|
void Join();
|
|
|
|
/**
|
|
* Kills the thread immediately. One still needs to call Join()
|
|
* afterwards.
|
|
*
|
|
* This is called from the threading::Manager and safe to execute
|
|
* during a signal handler.
|
|
*/
|
|
void Kill();
|
|
|
|
/** Called by child thread's launcher when it's done processing. */
|
|
ZEEK_DISABLE_TSAN void Done();
|
|
|
|
private:
|
|
// thread entry function.
|
|
static void* launcher(void* arg);
|
|
|
|
const char* name;
|
|
std::thread thread;
|
|
bool started; // Set to to true once running.
|
|
std::atomic_bool terminating; // Set to to true to signal termination.
|
|
std::atomic_bool killed; // Set to true once forcefully killed.
|
|
|
|
// For implementing Fmt().
|
|
uint32_t buf_len;
|
|
char* buf;
|
|
|
|
// For implementing Strerror().
|
|
char* strerr_buffer;
|
|
|
|
static uint64_t thread_counter;
|
|
};
|
|
|
|
} // namespace zeek::threading
|