*/
+#include "exitcodes.h"
#include "inspircd.h"
+#include <iostream>
/** Reference table, contains all current handlers
**/
*/
std::set<int> SocketEngine::trials;
-int SocketEngine::MAX_DESCRIPTORS;
+size_t SocketEngine::MaxSetSize = 0;
/** Socket engine statistics: count of various events, bandwidth usage
*/
this->fd = FD;
}
+void EventHandler::OnEventHandlerWrite()
+{
+}
+
+void EventHandler::OnEventHandlerError(int errornum)
+{
+}
+
+void SocketEngine::InitError()
+{
+ std::cerr << con_red << "FATAL ERROR!" << con_reset << " Socket engine initialization failed. " << strerror(errno) << '.' << std::endl;
+ ServerInstance->QuickExit(EXIT_STATUS_SOCKETENGINE);
+}
+
+void SocketEngine::LookupMaxFds()
+{
+ struct rlimit limits;
+ if (!getrlimit(RLIMIT_NOFILE, &limits))
+ MaxSetSize = limits.rlim_cur;
+
+#if defined __APPLE__
+ limits.rlim_cur = limits.rlim_max == RLIM_INFINITY ? OPEN_MAX : limits.rlim_max;
+#else
+ limits.rlim_cur = limits.rlim_max;
+#endif
+ if (!setrlimit(RLIMIT_NOFILE, &limits))
+ MaxSetSize = limits.rlim_cur;
+}
+
void SocketEngine::ChangeEventMask(EventHandler* eh, int change)
{
int old_m = eh->event_mask;
int mask = eh->event_mask;
eh->event_mask &= ~(FD_ADD_TRIAL_READ | FD_ADD_TRIAL_WRITE);
if ((mask & (FD_ADD_TRIAL_READ | FD_READ_WILL_BLOCK)) == FD_ADD_TRIAL_READ)
- eh->HandleEvent(EVENT_READ, 0);
+ eh->OnEventHandlerRead();
if ((mask & (FD_ADD_TRIAL_WRITE | FD_WRITE_WILL_BLOCK)) == FD_ADD_TRIAL_WRITE)
- eh->HandleEvent(EVENT_WRITE, 0);
+ eh->OnEventHandlerWrite();
}
}
int SocketEngine::RecvFrom(EventHandler* fd, void *buf, size_t len, int flags, sockaddr *from, socklen_t *fromlen)
{
int nbRecvd = recvfrom(fd->GetFd(), (char*)buf, len, flags, from, fromlen);
- if (nbRecvd > 0)
- stats.Update(nbRecvd, 0);
+ stats.UpdateReadCounters(nbRecvd);
return nbRecvd;
}
int SocketEngine::Send(EventHandler* fd, const void *buf, size_t len, int flags)
{
int nbSent = send(fd->GetFd(), (const char*)buf, len, flags);
- if (nbSent > 0)
- stats.Update(0, nbSent);
+ stats.UpdateWriteCounters(nbSent);
return nbSent;
}
int SocketEngine::Recv(EventHandler* fd, void *buf, size_t len, int flags)
{
int nbRecvd = recv(fd->GetFd(), (char*)buf, len, flags);
- if (nbRecvd > 0)
- stats.Update(nbRecvd, 0);
+ stats.UpdateReadCounters(nbRecvd);
return nbRecvd;
}
int SocketEngine::SendTo(EventHandler* fd, const void *buf, size_t len, int flags, const sockaddr *to, socklen_t tolen)
{
int nbSent = sendto(fd->GetFd(), (const char*)buf, len, flags, to, tolen);
- if (nbSent > 0)
- stats.Update(0, nbSent);
+ stats.UpdateWriteCounters(nbSent);
return nbSent;
}
int SocketEngine::WriteV(EventHandler* fd, const IOVector* iovec, int count)
{
int sent = writev(fd->GetFd(), iovec, count);
- if (sent > 0)
- stats.Update(0, sent);
+ stats.UpdateWriteCounters(sent);
return sent;
}
return shutdown(fd, how);
}
-void SocketEngine::Statistics::Update(size_t len_in, size_t len_out)
+void SocketEngine::Statistics::UpdateReadCounters(int len_in)
+{
+ CheckFlush();
+
+ ReadEvents++;
+ if (len_in > 0)
+ indata += len_in;
+ else if (len_in < 0)
+ ErrorEvents++;
+}
+
+void SocketEngine::Statistics::UpdateWriteCounters(int len_out)
{
CheckFlush();
- indata += len_in;
- outdata += len_out;
+
+ WriteEvents++;
+ if (len_out > 0)
+ outdata += len_out;
+ else if (len_out < 0)
+ ErrorEvents++;
}
void SocketEngine::Statistics::CheckFlush() const