**/
/* }}} */
-#include "cycript.hpp"
-#include "JavaScript.hpp"
-
-#include "Pooling.hpp"
-#include "Parser.hpp"
-
-#include "Cycript.tab.hh"
-
#include <Foundation/Foundation.h>
#include <pthread.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/un.h>
+#include "cycript.hpp"
+
+#include "JavaScript.hpp"
+#include "Parser.hpp"
+#include "Pooling.hpp"
+
+#include "Cycript.tab.hh"
+#include "Driver.hpp"
+
struct CYExecute_ {
CYPool &pool_;
const char * volatile data_;
return NULL;
}
-extern "C" void CYHandleClient(CYPool &pool, int socket) {
- CYClient *client(new(pool) CYClient(socket));
+extern "C" void CYHandleClient(int socket) {
+ // XXX: this leaks memory... really?
+ CYPool *pool(new CYPool());
+ CYClient *client(new(*pool) CYClient(socket));
_assert(pthread_create(&client->thread_, NULL, &OnClient, client) == 0);
}
sprintf(address.sun_path, "/tmp/.s.cy.%u", pid);
_syscall(connect(socket, reinterpret_cast<sockaddr *>(&address), SUN_LEN(&address)));
-
- // XXX: this leaks memory... really?
- CYHandleClient(*new CYPool(), socket);
+ CYHandleClient(socket);
} catch (const CYException &error) {
CYPool pool;
fprintf(stderr, "%s\n", error.PoolCString(pool));
}
}
+
+struct CYServer {
+ pthread_t thread_;
+ uint16_t port_;
+ int socket_;
+
+ CYServer(uint16_t port) :
+ port_(port),
+ socket_(-1)
+ {
+ }
+
+ ~CYServer() {
+ if (socket_ != -1)
+ _syscall(close(socket_));
+ }
+
+ void Listen() {
+ socket_ = _syscall(::socket(PF_INET, SOCK_STREAM, 0)); try {
+ sockaddr_in address;
+ address.sin_family = AF_INET;
+ address.sin_addr.s_addr = INADDR_ANY;
+ address.sin_port = htons(port_);
+ _syscall(::bind(socket_, reinterpret_cast<sockaddr *>(&address), sizeof(address)));
+
+ _syscall(::listen(socket_, -1));
+
+ for (;;) {
+ socklen_t length(sizeof(address));
+ int socket(_syscall(::accept(socket_, reinterpret_cast<sockaddr *>(&address), &length)));
+ CYHandleClient(socket);
+ }
+ } catch (const CYException &error) {
+ CYPool pool;
+ fprintf(stderr, "%s\n", error.PoolCString(pool));
+ }
+ }
+};
+
+static void *OnServer(void *data) {
+ CYServer *server(reinterpret_cast<CYServer *>(data));
+ server->Listen();
+ delete server;
+ return NULL;
+}
+
+extern "C" void CYListenServer(short port) {
+ CYInitializeDynamic();
+
+ CYServer *server(new CYServer(port));
+ _assert(pthread_create(&server->thread_, NULL, &OnServer, server) == 0);
+}