Working Version

This commit is contained in:
Brad Arant 2021-08-07 11:47:54 -07:00
parent 46f98dff69
commit 20d5c99517
10 changed files with 82 additions and 84 deletions

View File

@ -8,11 +8,12 @@ namespace core {
return 0; return 0;
} }
void Command::output(Session *session) {} void Command::output(std::stringstream &out) {
out << "Write your own command description here for the help system." << std::endl;
}
bool Command::check(coreutils::ZString request) { bool Command::check(coreutils::ZString request) {
return request[0].equals(name); return request[0].equals(name);
} }
void Command::setName(std::string name) { void Command::setName(std::string name) {

View File

@ -9,36 +9,36 @@
namespace core { namespace core {
class CommandList; class CommandList;
class Session; class Session;
/// ///
/// Command /// Command
/// ///
/// Use the Command object in combination with a CommandList object to maintain /// Use the Command object in combination with a CommandList object to maintain
/// a list of functions that can be invoked as a result of processing a request. /// a list of functions that can be invoked as a result of processing a request.
/// ///
class Command { class Command {
public: public:
/// ///
/// Implement check method to provide a special check rule upon the request to see /// Implement check method to provide a special check rule upon the request to see
/// if the command should be processed. /// if the command should be processed.
/// ///
/// The default rule is to verify that the first token in the request string matches /// The default rule is to verify that the first token in the request string matches
/// the name given on the registration of the command to the CommandList. This can /// the name given on the registration of the command to the CommandList. This can
/// be overridden by implementing the check() method to perform the test and return /// be overridden by implementing the check() method to perform the test and return
/// the condition of the command. /// the condition of the command.
/// ///
/// @param request The request passed to the parser to check the rule. /// @param request The request passed to the parser to check the rule.
/// @return Return true to execute the command. Returning false will cause no action /// @return Return true to execute the command. Returning false will cause no action
/// on this command. /// on this command.
/// ///
virtual bool check(coreutils::ZString request); virtual bool check(coreutils::ZString request);
/// ///
/// This method is used to implement the functionality of the requested command. /// This method is used to implement the functionality of the requested command.
/// This pure virtual function must be implemented in your inheriting object. /// This pure virtual function must be implemented in your inheriting object.
@ -49,17 +49,17 @@ namespace core {
/// @return Returns 0 if execution of the command was successful. Otherwise returns /// @return Returns 0 if execution of the command was successful. Otherwise returns
/// a non-zero value indicating an error condition. /// a non-zero value indicating an error condition.
/// ///
virtual int processCommand(coreutils::ZString &request, TCPSession &session); virtual int processCommand(coreutils::ZString &request, TCPSession &session);
/// ///
/// Specify the output that will occur to the specified session. /// Specify the output that will occur to the specified session.
/// ///
/// @param session The session that will receive the output. /// @param session The session that will receive the output.
/// ///
virtual void output(Session *session); virtual void output(std::stringstream &out);
/// ///
/// Set the name of this command used in default rule checking during request parsing. /// Set the name of this command used in default rule checking during request parsing.
/// NOTE: You do not need to call this under normal conditions as adding a Command /// NOTE: You do not need to call this under normal conditions as adding a Command
@ -68,16 +68,16 @@ namespace core {
/// ///
/// @param name Specify the name of this command for default parsing. /// @param name Specify the name of this command for default parsing.
/// ///
void setName(std::string name); void setName(std::string name);
std::string getName(); std::string getName();
private: private:
std::string name; std::string name;
}; };
} }
#endif #endif

View File

@ -26,20 +26,20 @@ namespace core {
/// ///
void add(Command &command, std::string name = ""); void add(Command &command, std::string name = "");
/// ///
/// Remove a command object from the command list. /// Remove a command object from the command list.
/// ///
void remove(Command &command); void remove(Command &command);
/// ///
/// Use this method to apply a parsed ZString to the command set and execute /// Use this method to apply a parsed ZString to the command set and execute
/// the matching parameter. The selected command will return a true on a call /// the matching parameter. The selected command will return a true on a call
/// to check(). If there is a handler that has a grab on the process handler /// to check(). If there is a handler that has a grab on the process handler
/// then control is given to the process handler holding the grab on the input. /// then control is given to the process handler holding the grab on the input.
/// ///
bool processRequest(coreutils::ZString &request, TCPSession &session); bool processRequest(coreutils::ZString &request, TCPSession &session);
/// ///
@ -47,32 +47,32 @@ namespace core {
/// all further input from the socket. Use releaseGrab() method to release the session /// all further input from the socket. Use releaseGrab() method to release the session
/// back to normal command processing. /// back to normal command processing.
/// ///
bool grabInput(TCPSession &session, Command &command); bool grabInput(TCPSession &session, Command &command);
/// ///
/// ///
/// ///
void clearGrab(TCPSession &session); void clearGrab(TCPSession &session);
/// ///
/// ///
/// ///
int processCommand(coreutils::ZString &request, TCPSession &session); int processCommand(coreutils::ZString &request, TCPSession &session);
protected: protected:
/// ///
/// The vector of all registered commands. /// The vector of all registered commands.
/// ///
std::vector<Command *> commands; std::vector<Command *> commands;
std::string delimiter; std::string delimiter;
}; };
} }
#endif #endif

View File

@ -4,18 +4,18 @@
#include "Log.h" #include "Log.h"
namespace core { namespace core {
ConsoleServer::ConsoleServer(EPoll &ePoll, IPAddress address) : TCPServer(ePoll, address, "Console") { ConsoleServer::ConsoleServer(EPoll &ePoll, IPAddress address) : TCPServer(ePoll, address, "Console") {
coreutils::Log(this); coreutils::Log(this);
} }
void ConsoleServer::logSend(std::string out) { void ConsoleServer::logSend(std::string out) {
for(auto *session : sessions) for(auto *session : sessions)
((ConsoleSession *)session)->writeLog(out); ((ConsoleSession *)session)->writeLog(out);
} }
TCPSession * ConsoleServer::getSocketAccept(EPoll &ePoll) { TCPSession * ConsoleServer::getSocketAccept(EPoll &ePoll) {
return new ConsoleSession(ePoll, *this); return new ConsoleSession(ePoll, *this);
} }
} }

View File

@ -113,7 +113,7 @@ namespace core {
event.data.ptr = socket; event.data.ptr = socket;
event.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP | EPOLLET; event.events = EPOLLIN | EPOLLONESHOT | EPOLLRDHUP | EPOLLET;
if(socket->needsToWrite()) if(socket->needsToWrite())
event.events |= EPOLLWRNORM; event.events |= EPOLLWRNORM;
epoll_ctl(epfd, EPOLL_CTL_MOD, socket->getDescriptor(), &event); epoll_ctl(epfd, EPOLL_CTL_MOD, socket->getDescriptor(), &event);
} }

12
EPoll.h
View File

@ -27,17 +27,17 @@ namespace core {
/// Threads are used to establish a read queue for epoll. The desired number of threads (or /// Threads are used to establish a read queue for epoll. The desired number of threads (or
/// queues) is established by a parameter on the start method. /// queues) is established by a parameter on the start method.
/// ///
class EPoll : public Command { class EPoll : public Command {
public: public:
/// ///
/// The constructor for the BMAEPoll object. /// The constructor for the BMAEPoll object.
/// ///
EPoll(); EPoll();
/// ///
/// The destructor for the BMAEPoll object. /// The destructor for the BMAEPoll object.
/// ///

View File

@ -63,10 +63,8 @@ namespace core {
return new TCPSession(ePoll, *this); return new TCPSession(ePoll, *this);
} }
void TCPServer::output(TCPSession *session) { void TCPServer::output(std::stringstream &out) {
std::stringstream out; out << "Use the 'help' command to list the commands for this server." << std::endl;
out << "|" << session->ipAddress.getClientAddressAndPort();
session->send();
} }
int TCPServer::processCommand(coreutils::ZString &request, TCPSession &session) { int TCPServer::processCommand(coreutils::ZString &request, TCPSession &session) {

View File

@ -85,7 +85,7 @@ namespace core {
void removeFromSessionList(TCPSession *session); void removeFromSessionList(TCPSession *session);
void output(TCPSession *session); ///<Output the consoles array to the console. void output(std::stringstream &out); ///<Output the consoles array to the console.
/// ///
/// ///

View File

@ -22,7 +22,7 @@ namespace core {
void TCPSession::onRegistered() { void TCPSession::onRegistered() {
onConnected(); onConnected();
protocol((char *)""); protocol(coreutils::ZString(""));
send(); send();
if(term) if(term)
shutdown("termination requested"); shutdown("termination requested");

View File

@ -2,23 +2,23 @@
#include "EPoll.h" #include "EPoll.h"
namespace core { namespace core {
Thread::Thread(EPoll &ePoll) : ePoll(ePoll) {} Thread::Thread(EPoll &ePoll) : ePoll(ePoll) {}
Thread::~Thread() {} Thread::~Thread() {}
void Thread::start() { void Thread::start() {
_thread = new std::thread(&Thread::run, this); _thread = new std::thread(&Thread::run, this);
} }
void Thread::join() { void Thread::join() {
_thread->join(); _thread->join();
} }
std::string Thread::getStatus() { std::string Thread::getStatus() {
return status; return status;
} }
pid_t Thread::getThreadId() { pid_t Thread::getThreadId() {
return threadId; return threadId;
} }
@ -26,44 +26,43 @@ namespace core {
int Thread::getCount() { int Thread::getCount() {
return count; return count;
} }
void Thread::output(std::stringstream &data) { void Thread::output(std::stringstream &data) {
data << "|" << getThreadId(); data << "|" << getThreadId();
data << "|" << getStatus(); data << "|" << getStatus();
data << "|" << getCount(); data << "|" << getCount();
} }
void Thread::run() { void Thread::run() {
threadId = syscall(SYS_gettid); threadId = syscall(SYS_gettid);
coreutils::Log(coreutils::LOG_DEBUG_1) << "Thread started with thread id " << threadId << "."; coreutils::Log(coreutils::LOG_DEBUG_1) << "Thread started with thread id " << threadId << ".";
count = 0; count = 0;
struct epoll_event events[50]; struct epoll_event events[50];
while(1) { while(1) {
if(ePoll.isStopping()) if(ePoll.isStopping())
break; break;
status = "WAITING"; status = "WAITING";
int rc = epoll_wait(ePoll.getDescriptor(), events, 50, -1); int rc = epoll_wait(ePoll.getDescriptor(), events, 50, -1);
status = "RUNNING"; status = "RUNNING";
if(rc < 0) { if(rc < 0) {
// TODO: Make log entry indicating status received and ignore for now. // TODO: Make log entry indicating status received and ignore for now.
} else if(rc == 0) { } else if(rc == 0) {
break; break;
} else if(rc > 0) { } else if(rc > 0) {
for(int ix = 0; ix < rc; ++ix) { for(int ix = 0; ix < rc; ++ix) {
++count; ++count;
if(((Socket *)events[ix].data.ptr)->eventReceived(events[ix])) if(((Socket *)events[ix].data.ptr)->eventReceived(events[ix]))
ePoll.resetSocket((Socket *)events[ix].data.ptr); ePoll.resetSocket((Socket *)events[ix].data.ptr);
} }
} }
} }
coreutils::Log(coreutils::LOG_DEBUG_1) << "Thread ending with thread id " << threadId << "."; coreutils::Log(coreutils::LOG_DEBUG_1) << "Thread ending with thread id " << threadId << ".";
} }