From: ryo-dairiki <ryo...@us...> - 2006-05-29 15:08:34
|
Update of /cvsroot/scim/scim-bridge/agent In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv19615/agent Added Files: Tag: plaintext scim-bridge-agent-socket-listener.h scim-bridge-agent-client-listener.cpp scim-bridge-agent-socket-listener.cpp scim-bridge-agent-client-listener.h Removed Files: Tag: plaintext scim-bridge-agent-client-peer.h scim-bridge-agent-client-peer.cpp Log Message: --- NEW FILE: scim-bridge-agent-client-listener.cpp --- #include <unistd.h> #include <sys/select.h> #include <sys/socket.h> #include "scim-bridge-agent-client-listener.h" #include "scim-bridge-agent-connection-lost-event.h" #include "scim-bridge-messenger.h" /* Class definition */ class ScimBridgeAgentClientListenerImpl: public ScimBridgeAgentClientListener { public: ScimBridgeAgentClientListenerImpl (int new_socket_fd); ~ScimBridgeAgentClientListenerImpl (); /* The following methods are semi-public */ bool is_connection_active (); void connection_lost (); const ScimBridgeMessage *pop_message (); protected: virtual void do_close_event_client () = 0; private: pthread_t socket_writer_thread; pthread_t socket_reader_thread; ScimBridgeMessenger *messenger; }; /* Helper functions */ static void *run_socket_reader (void *arg) { ScimBridgeAgentClientListenerImpl *client_listener = static_cast<ScimBridgeAgentClientListenerImpl*> (arg); while (client_listener->is_connection_active ()) { const ScimBridgeAgentMessage *message; if (scim_bridge_messenger_receive_message (messenger, &message)) { client_listener->connection_lost (); scim_bridge_free_message (message); return NULL; } else { client_listener->push_message (message); scim_bridge_free_message (message); } } return NULL; } static void *run_socket_writer (void *arg) { ScimBridgeAgentClientListenerImpl *client_peer = static_cast<ScimBridgeAgentClientListenerImpl*> (arg); while (client_peer->is_connection_active ()) { const ScimBridgeMessage *message = client_peer->pop_message (); if (message == NULL) continue; if (scim_bridge_messenger_send_message (messenger, message)) { scim_bridge_free_message (message); return NULL; } else { scim_bridge_free_message (message); } } return NULL; } /* Implementations */ ScimBridgeAgentClientListener *ScimBridgeAgentClientListener::alloc (int new_socket_fd) { return new ScimBridgeAgentClientListenerImpl (new_socket_fd); } ScimBridgeAgentClientListenerImpl::ScimBridgeAgentClientListenerImpl (int socket_fd) { messenger = scim_bridge_alloc_messenger (socket_fd); if (pthread_create (&socket_writer_thread, run_socket_writer) || pthread_create (&socket_reader_thread, run_socket_reader)) { scim_bridge_psyslog (SYSLOG_CRITICAL, "Cannot invoke message IO threads: %s", strerror (errno)); abort (); } } ScimBridgeAgentClientListenerImpl::~ScimBridgeAgentClientListenerImpl () { scim_bridge_free_messenger(messenger); } bool ScimBridgeAgentClientListenerImpl::is_connection_active () { return !scim_bridge_messenger_is_closed (messenger); } const ScimBridgeMessage *ScimBridgeAgentClientListenerImpl::pop_message () { const ScimBridgeAgentEvent *event = pop_event (); ScimBridgeMessage *message = NULL; if (event != NULL) { switch (event->get_code ()) { default: break; } } delete event; return message; } void ScimBridgeAgentClientListenerImpl::connection_lost () { get_event_server ()->push_event (new ScimBridgeAgentConnectionLostEvent (this)); } void ScimBridgeAgentClientListenerImpl::do_close_event_client () { scim_bridge_messenger_close (messenger); pthread_kill (socket_writer_thread, SIGNOTIFY); pthread_join (socket_writer_thread, NULL); pthread_kill (socket_reader_thread, SIGNOTIFY); pthread_join (socket_reader_thread, NULL); } --- NEW FILE: scim-bridge-agent-socket-listener.cpp --- #include <errno.h> #include <pthread.h> #include <sys/socket.h> #include <sys/types.h> #include "scim-bridge-agent-output.h" #include "scim-bridge-agent-socket-closed-event.h" #include "scim-bridge-agent-connection-established-event.h" #include "scim-bridge-agent-socket-listener.h" /* Class definition */ class ScimBridgeAgentSocketListenerImpl: public ScimBridgeAgentSocketListener { public: ScimBridgeAgentSocketListenerImpl (const char *socket_path); ~ScimBridgeAgentSocketListenerImpl (); /* The following methods are semi-public */ int get_socket_fd (); void socket_closed (); protected: void do_close_event_client (); private: int socket_fd; pthread_t socket_listener_thread; }; /* Helper functions */ void *run_socket_listener (void *arg) { scim_bridge_pdebugln (SCIM_BRIDGE_DEBUG_AGENT, 5, "run_socket_listener"); ScimBridgeAgentSocketListenerImpl *socket_listener = static_cast<ScimBridgeAgentSocketListenerImpl*> (arg); while (socket_listener->get_socket_fd () != 0) { scim_bridge_pdebugln (SCIM_BRIDGE_DEBUG_AGENT, 3, "Waiting for connection..."); int fd = -1; struct sockaddr_un empty_socket_addr; socklen_t emtpy_socket_size = sizeof (empty_socket_addr); fd = accept (socket_listener->get_socket_fd (), (sockaddr*)&empty_socket_addr, &emtpy_socket_size); if (fd < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR || errno == 0) { continue; } else if (errno == EBADF) { socket_listener->socket_listener_exited (); return NULL; } else { scim_bridge_psyslogln ("An exception occured at run_socket_listener: %s", strerror (errno)); /* FIXME What if socket is broken by itself? */ socket_listener->socket_closed (); return NULL; } usleep (50); } else { scim_bridge_pdebugln (SCIM_BRIDGE_DEBUG_AGENT, 5, "Connection accepted."); socket_client->connection_accepted (fd); } } } /* Implementations */ ScimBridgeAgentSocketListener *ScimBridgeAgentSocketListener::alloc (const char *socket_path) { return new ScimBridgeAgentSocketListenerImpl (socket_path); } ScimBridgeAgentSocketListenerImpl::ScimBridgeAgentSocketListenerImpl (const char *socket_path) { socket_fd = socket (PF_UNIX, SOCK_STREAM, 0); if (socket_fd < 0) { scim_bridge_psyslogln (SYSLOG_ERROR, "Cannot create an unix domain socket: %s", strerror (errno)); abort (); } struct sockaddr_un socket_addr; memset (&socket_addr, 0, sizeof (struct sockaddr_un)); socket_addr.sun_family = AF_UNIX; strcpy (socket_addr.sun_path, socket_path); unlink (socket_path); if (bind (socket_fd, (struct sockaddr*)&socket_addr, sizeof (struct sockaddr_un)) != 0) { scim_bridge_psyslogln (SYSLOG_ERROR, "Cannot bind the socket: %s", strerror (errno)); abort (); } if (listen (socket_fd, 64)) { scim_bridge_psyslogln ("Cannot start listening the socket: %s", strerror (errno)); abort (); } if (pthread_create (&socket_listener_thread, NULL, &run_socket_listener, this)) { scim_bridge_psyslog (SYSLOG_CRITICAL, "Cannot invoke socket listener thread: %s", strerror (errno)); abort (); } } ScimBridgeAgentSocketListenerImpl::~ScimBridgeAgentSocketListenerImpl () { } int ScimBridgeAgentSocketListenerImpl::get_socket_fd () { return socket_fd; } void ScimBridgeAgentSocketListenerImpl::socket_closed () { get_event_server ()->push_event (new ScimBridgeAgentSocketClosedEvent ()); } void ScimBridgeAgentSocketListenerImpl::do_close_event_client () { const int tmp_socket_fd = socket_fd; socket_fd = -1; shutdown (tmp_socket_fd, SHUT_RDWR); close (tmp_socket_fd); pthread_kill (socket_listener_thread, SIGNOTIFY); pthread_join (socket_listener_thread, NULL); } --- scim-bridge-agent-client-peer.cpp DELETED --- --- scim-bridge-agent-client-peer.h DELETED --- --- NEW FILE: scim-bridge-agent-socket-listener.h --- #ifndef SCIMBRIDGEAGENTSOCKETLISTENER_H_ #define SCIMBRIDGEAGENTSOCKETLISTENER_H_ #include "scim-bridge.h" #include "scim-bridge-agent-event-client.h" class ScimBridgeAgentSocketListener: public ScimBridgeAgentEventClient { public: static ScimBridgeAgentSocketListener *alloc (const char *socket_path); virtual ~ScimBridgeAgentSocketListener () {} protected: ScimBridgeAgentSocketListener () {} void do_close_event_client (); }; #endif /*SCIMBRIDGEAGENTSOCKETLISTENER_H_*/ --- NEW FILE: scim-bridge-agent-client-listener.h --- #ifndef SCIMBRIDGEAGENTCLIENTLISTENER_H_ #define SCIMBRIDGEAGENTCLIENTLISTENER_H_ #include "scim-bridge-agent-event-client.h" class ScimBridgeAgentClientListener: public ScimBridgeAgentEventClient { public: static ScimBridgeAgentClientListener *alloc (int new_socket_fd); virtual ~ScimBridgeAgentClientListener () {} protected: ScimBridgeAgentClientListener () {} virtual void do_close_event_client () = 0; }; #endif /*SCIMBRIDGEAGENTCLIENTLISTENER_H_*/ |