- INotify/Thread epoll dispatch was silently dropping every live core::INotify event (an isKnownINotify registry fixes it) - this had broken mail delivery for over a week, masked by routine restarts. - TCPServer::lock self-deadlocked every admin-console connection via a plain std::mutex being re-entered; switched to recursive_mutex. - TLS.cpp/h: SNI-based certificate selection (addSNIContext), the groundwork for multi-tenant TLS (qualityiron.vegas alongside barant.com on one APIServer process). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
74 lines
2.7 KiB
C++
74 lines
2.7 KiB
C++
#ifndef __INotify_h__
|
|
# define __INotify_h__
|
|
|
|
#include "Socket.h"
|
|
#include <set>
|
|
#include <mutex>
|
|
|
|
namespace core {
|
|
|
|
class INotify : Socket {
|
|
|
|
public:
|
|
INotify(EPoll &ePoll);
|
|
~INotify();
|
|
|
|
int addWatch(coreutils::ZString &watch);
|
|
void removeWatch(int wd);
|
|
|
|
void onDataReceived(coreutils::ZString &data) override;
|
|
|
|
virtual void inAccess(coreutils::ZString name) {}
|
|
virtual void inAttrib(std::string name) {}
|
|
virtual void inCloseWrite(std::string name) {}
|
|
virtual void inCloseNoWrite(std::string name) {}
|
|
virtual void inCreate(coreutils::ZString &name) {}
|
|
virtual void inDelete(std::string name) {}
|
|
virtual void inDeleteSelf(std::string name) {}
|
|
virtual void inModify(std::string name) {}
|
|
virtual void inMoveSelf(std::string name) {}
|
|
virtual void inMovedFrom(std::string name) {}
|
|
virtual void inMovedTo(std::string name) {}
|
|
virtual void inOpen(std::string name) {}
|
|
|
|
/// core::INotify is a long-lived Socket subclass that is neither
|
|
/// a TCPSession (shared_ptr/pin()-owned) nor a listening
|
|
/// TCPServer - it is normally embedded as a base subobject of a
|
|
/// server object constructed once in main() and living for the
|
|
/// whole process (e.g. mail::SMTPServer's queue-directory watch).
|
|
/// Thread::run()'s epoll dispatch only ever recognized those two
|
|
/// categories of raw pointer as safe to call directly (see
|
|
/// TCPServer::isKnownListeningSocket()'s own doc comment) -
|
|
/// anything else fell through to the "stale/unrecognized epoll
|
|
/// event" branch and was silently dropped forever. Confirmed
|
|
/// live: a real IN_CREATE event on a mail queue directory logged
|
|
/// exactly that "Ignoring stale/unrecognized epoll event" line
|
|
/// and the newly queued message was never delivered - it just sat
|
|
/// in the queue until the next process restart, whose
|
|
/// processExisting() directory scan (a plain synchronous loop,
|
|
/// entirely independent of epoll) happened to flush the backlog
|
|
/// and made the bug look intermittent. Registering the instance here,
|
|
/// mirroring listeningSockets() exactly, gives Thread::run() the
|
|
/// same kind of safe "yes, dispatch to this raw pointer directly"
|
|
/// signal for INotify objects too.
|
|
static bool isKnownINotify(void *ptr) {
|
|
std::lock_guard<std::mutex> guard(knownINotifiesMutex());
|
|
return knownINotifies().count(ptr) > 0;
|
|
}
|
|
|
|
private:
|
|
static std::mutex &knownINotifiesMutex() {
|
|
static std::mutex m;
|
|
return m;
|
|
}
|
|
static std::set<void *> &knownINotifies() {
|
|
static std::set<void *> s;
|
|
return s;
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|