privacore-open-source-searc.../Loop.h
Ivan Skytte Jørgensen beeddcf35d Got rid of gb-include.h
2018-07-26 17:29:51 +02:00

149 lines
4.8 KiB
C++

// Matt Wells, Copyright Apr 2001
// . core class for handling interupts-based i/o on non-blocking descriptors
// . when an fd/state/callback is registered for reading we call your callback // when fd has a read event (same for write and sleeping)
#ifndef GB_LOOP_H
#define GB_LOOP_H
#include "GbMutex.h"
#include <inttypes.h>
int gbsystem(const char *cmd);
/**
* Print stack trace
*/
void printStackTrace (bool print_location = false);
class Slot;
// linux 2.2 kernel has this limitation
#define MAX_NUM_FDS 1024
// . niceness can only be 0, 1 or 2
// . we use 0 for query traffic
// . we use 1 for merge disk threads
// . we use 2 for indexing/spidering
// . 0 will use the high priority udp server, g_udpServer2
// . 1+ will use the low priority udp server, g_udpServer
// . 0 niceness for disk threads will cancel other threads before launching
// . 1+ niceness threads will be set to lowest priority using setpriority()
// . 1 niceness disk thread, when running, will not allow niceness 2 to launch
//#define MAX_NICENESS 2
class Loop {
public:
// contructor and stuff
Loop();
~Loop();
// free up all our mem
void reset();
// set up the signal handlers or block the signals for queueing
bool init();
// . call this to begin polling/selecting of all registed fds
// . returns false on error
[[ noreturn ]] void runLoop();
// . register this "fd" with "callback"
// . "callback" will be called when fd is ready for reading
// . "timeout" is -1 if this never timesout
bool registerReadCallback(int fd, void *state, void (*callback)(int fd, void *state),
const char *description, int32_t niceness);
// . register this "fd" with "callback"
// . "callback" will be called when fd is ready for reading
// . "callback" will be called when there is an error on fd
bool registerWriteCallback(int fd, void *state, void (*callback)(int fd, void *state),
const char *description, int32_t niceness);
// . register this callback to be called every second
// . TODO: implement "seconds" parameter
bool registerSleepCallback(int32_t milliseconds, void *state, void (*callback)(int fd, void *state),
const char *description, int32_t niceness = 1, bool immediate = false);
// unregister call back for reading, writing or sleeping
void unregisterReadCallback ( int fd, void *state , void (* callback)(int fd,void *state) );
void unregisterWriteCallback ( int fd, void *state , void (* callback)(int fd,void *state) );
void unregisterSleepCallback ( void *state , void (* callback)(int fd,void *state) );
// sets up for signal capture by us, g_loop
bool setNonBlocking(int fd);
// . keep this public so sighandler() can call it
// . we also call it from HttpServer::getMsgPieceWrapper() to
// notify a socket that it's m_sendBuf got some new data to send
void callCallbacks_ass (bool forReading, int fd, int64_t now = 0LL,
int32_t niceness = -1 );
void wakeupPollLoop();
bool m_isDoingLoop;
// the sighupHandler() will set this to 1 when we receive
// a SIGHUP, 2 if a thread crashed, 3 if we got a SIGPWR
char m_shutdown;
// called when sigqueue overflows and we gotta do a select() or poll()
void doPoll ( );
private:
void unregisterCallback ( Slot **slots , int fd , void *state ,
void (* callback)(int fd,void *state) ,
bool forReading );
bool addSlot(bool forReading, int fd, void *state, void (*callback)(int fd, void *state),
int32_t niceness, const char *description, int32_t tick = 0x7fffffff, bool immediate = false);
// now we use a linked list of pre-allocated slots to avoid a malloc
// failure which can cause the merge to dump with "URGENT MERGE FAILED"
// message becaise it could not register the sleep wrapper to wait
Slot *getEmptySlot ( ) ;
void returnSlot ( Slot *s ) ;
// . these arrays map an fd to a Slot (see above for Slot definition)
// . that slot may chain to other slots if more than one procedure
// is waiting on a file to become available for reading/writing
// . these fd's are real, not virtual
// . m_read/writeFds[i] is NULL if no one is waiting on fd #i
// . fd of MAX_NUM_FDS is used for sleep callbacks
// . fd of MAX_NUM_FDS+1 is used for thread exit callbacks
Slot *m_readSlots [MAX_NUM_FDS+2];
Slot *m_writeSlots [MAX_NUM_FDS+2];
// the minimal tick time in milliseconds (ms)
int32_t m_minTick;
// now we pre-allocate our slots to prevent nasty coredumps from merge
// because it could not register a sleep callback with us
Slot *m_slots;
Slot *m_head;
Slot *m_tail;
Slot *m_callbacksNext; //in case we unregister the "next" callback
GbMutex m_slotMutex; //protects all slot linked list modification and traversal
int m_pipeFd[2]; //used for waking up from select/poll
int64_t m_lastKeepaliveTimestamp;
};
extern class Loop g_loop;
#endif // GB_LOOP_H