#include "plaqui/server/runnable.h"
#include <socket++/sockinet.h>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión.
class Connection: public Runnable {
*/
Connection(const sockbuf::sockdesc& sd);
- /**
- * Constructor.
- *
- * \param socket Socket a usar en la conexión.
- */
- //Connection(const sockinetbuf& sb);
-
/**
* Constructor.
*
}
+}
+
#endif // PLAQUI_CONNECTION_H
#include "plaqui/server/connection.h"
#include <string>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión para enviar comandos de control a una planta.
class ControlClient: public Connection {
}
+}
+
#endif // PLAQUI_CONTROLCLIENT_H
#include "plaqui/server/connection.h"
#include <socket++/sockinet.h>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión para recibir comandos de control para una planta.
class ControlServer: public Connection {
}
+}
#endif // PLAQUI_CONTROLSERVER_H
#include <socket++/sockinet.h>
#include <string>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión para recibir el estado de una planta.
class Receiver: public Connection {
}
+}
+
#endif // PLAQUI_RECEIVER_H
#include <map>
#include <string>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión.
class Request: public std::map<std::string, std::string> {
}
+}
+
#endif // PLAQUI_REQUEST_H
#define PLAQUI_RUNNABLE_H
#include <glibmm/thread.h>
+#include <sigc++/signal.h>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// ealizauna tarea (generalmente en un thread).
class Runnable {
+ // Tipos.
+
+ public:
+
+ /// Tipo de señal para indicar que se finalizó la tarea.
+ typedef SigC::Signal0<void> SignalFinished;
+
+ // Atributos.
+
private:
- // Thread en el cual correr la tarea.
+
+ /// Thread en el cual correr la tarea.
Glib::Thread* thread;
+ /// Indica si se debe frinalizar la tarea.
+ bool stop;
+
+ /// Señal que indica que se finalizó la tarea.
+ SignalFinished finished;
+
+ // Métodos.
+
+ private:
+
+ /**
+ * Corre la tarea controlando cuando termina.
+ *
+ * \param runner Objeto con la tarea a realizar.
+ */
+ static void static_run(Runnable* runner);
+
protected:
/// Realiza la terea.
Runnable(void);
/**
- * Comienza la tares.
+ * Comienza la tarea.
*
* \param detach Si es true se corre en un thread propio. Si no no
* retorna hasta que finaliza.
*/
virtual void run(bool detach = true);
+ /**
+ * Finaliza la tarea.
+ *
+ * \param attach Si es true, la función no retorna hasta que no
+ * finalice la tearea (no recomendable).
+ *
+ * \see Para saber cuando la tarea fue finalizada puede utilizar
+ * la señal signal_finished().
+ */
+ virtual void finish(bool attach = false);
+
+ /**
+ * Obtiene la señal que avisa cuando la tarea es finalizada.
+ *
+ * \see Para saber cuando la tarea fue finalizada puede utilizar
+ * la señal signal_finished().
+ */
+ SignalFinished& signal_finished(void);
+
};
}
+}
+
#endif // PLAQUI_RUNNABLE_H
#include <string>
#include <list>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/**
* Servidor de plantas químicas.
}
+}
+
#endif // PLAQUI_SERVER_H
#include <string>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión.
class String: public std::string {
}
+}
+
#endif // PLAQUI_STRING_H
#include "plaqui/server/connection.h"
#include <string>
-namespace Plaqui {
+namespace PlaQui {
+
+namespace Server {
/// Conexión para transmitir el estado de una planta.
class Transmitter: public Connection {
}
+}
+
#endif // PLAQUI_TRANSMITTER_H
#include "plaqui/server/connection.h"
#include <socket++/sockinet.h>
-using namespace Plaqui;
+using namespace PlaQui::Server;
Connection::Connection(const sockbuf::sockdesc& sd):
socket(sd) {
// XXX
#include <iostream>
-using namespace Plaqui;
+using namespace PlaQui::Server;
ControlClient::ControlClient(std::string host, int port):
Connection(sockbuf::sock_stream) {
#include <cstring>
#include <sstream>
-using namespace Plaqui;
+using namespace PlaQui::Server;
ControlServer::ControlServer(const sockbuf::sockdesc& sd):
Connection(sd) {
bool is_first = true;
while (!stop && socket.getline(buf, BUFFER_SIZE)) {
#ifdef DEBUG
- std::cerr << "Reciviendo (crudo): " << buf << std::endl;
+ std::cerr << "Reciviendo linea: " << buf << std::endl;
#endif // DEBUG
int len = strlen(buf);
// Si tiene un retorno de carro, lo elimina.
if (len && (buf[len-1] == '\r')) {
buf[--len] = '\0';
}
-#ifdef DEBUG
- std::cerr << "Reciviendo (sin \\r): " << buf << std::endl;
- std::cerr << "len: " << len << std::endl;
- if (len == 1) {
- std::cerr << std::hex << "Caracter: " << *buf << std::endl;
- }
-#endif // DEBUG
// Si tiene contenido, lo agrego a la información del request.
if (len) {
// Si es la primera línea, es el request.
#include "plaqui/server/receiver.h"
-using namespace Plaqui;
+using namespace PlaQui::Server;
Receiver::Receiver(int port, std::string host):
Connection(sockbuf::sock_dgram) {
# include <iostream>
#endif // DEBUG
-using namespace Plaqui;
+using namespace PlaQui::Server;
const std::string Request::CHARS_DIGIT = "0123456789";
# include <iostream>
#endif // DEBUG
-using namespace Plaqui;
+PlaQui::Server::Runnable::Runnable(void): thread(0), stop(false) {
+}
-Runnable::Runnable(void): thread(0) {
+void PlaQui::Server::Runnable::static_run(PlaQui::Server::Runnable* runner) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": runner = " << runner << std::endl;
+#endif // DEBUG
+ runner->real_run();
+ runner->signal_finished().emit();
+ delete runner;
}
-void Runnable::run(bool detach) {
+void PlaQui::Server::Runnable::run(bool detach) {
#ifdef DEBUG
std::cerr << __FILE__ << ": detach = " << detach << std::endl;
#endif // DEBUG
if (!Glib::thread_supported()) {
Glib::thread_init();
}
- // Corremos el thread.
+ // Corremos el thread en una funcion estática para poder destruirlo al
+ // finalizar, pasandole el puntero al objeto.
thread = Glib::Thread::create(
- SigC::slot_class(*this, &Runnable::real_run), true);
+ SigC::bind<Runnable*>(
+ SigC::slot(&PlaQui::Server::Runnable::static_run),
+ this),
+ true);
// Si no corremos la tarea normalmente.
} else {
real_run();
}
+void PlaQui::Server::Runnable::finish(bool attach) {
+#ifdef DEBUG
+ std::cerr << __FILE__ << ": attach = " << attach << std::endl;
+#endif // DEBUG
+ // TODO - necesita un mutex?
+ stop = true;
+ if (attach) {
+ thread->join();
+ }
+}
+
+PlaQui::Server::Runnable::SignalFinished&
+PlaQui::Server::Runnable::signal_finished(void) {
+ return finished;
+}
+
# include <iostream>
#endif // DEBUG
-using namespace Plaqui;
+using namespace PlaQui::Server;
Server::Server(int port):
socket(sockbuf::sock_stream) {
# include <iostream>
#endif // DEBUG
-using namespace Plaqui;
+using namespace PlaQui::Server;
const std::string String::SPACE_CHARS = " \t\n\r";
#include <socket++/sockinet.h>
#include <string>
-using namespace Plaqui;
+using namespace PlaQui::Server;
Transmitter::Transmitter(std::string host, int port):
Connection(sockbuf::sock_dgram) {
#include <exception>
using namespace std;
-using namespace Plaqui;
+using namespace PlaQui::Server;
int main(int argc, char* argv[]) {