void ForkExecChild::connect() { // set error state, clear it later m_state = DISCONNECTED; const char *address = getParentDBusAddress(); if (!address) { SE_THROW("cannot connect to parent, was not forked"); } SE_LOG_DEBUG(NULL, NULL, "ForkExecChild: connecting to parent with D-Bus address %s", address); GDBusCXX::DBusErrorCXX dbusError; GDBusCXX::DBusConnectionPtr conn = dbus_get_bus_connection(address, &dbusError, true /* always delay message processing */); if (!conn) { dbusError.throwFailure("connecting to server"); } m_state = CONNECTED; // start watching connection #ifdef GDBUS_CXX_HAVE_DISCONNECT conn.setDisconnect(boost::bind(&ForkExecChild::connectionLost, this)); #else // emulate disconnect with a pending method call class Parent : public GDBusCXX::DBusRemoteObject { public: Parent(const GDBusCXX::DBusConnectionPtr &conn) : GDBusCXX::DBusRemoteObject(conn, FORKEXEC_PARENT_PATH, FORKEXEC_PARENT_IFACE, FORKEXEC_PARENT_DESTINATION), m_watch(*this, "Watch") {} GDBusCXX::DBusClientCall0 m_watch; } parent(conn); parent.m_watch.start(boost::bind(&ForkExecChild::connectionLost, this)); #endif m_onConnect(conn); dbus_bus_connection_undelay(conn); }
void ForkExecParent::newClientConnection(GDBusCXX::DBusConnectionPtr &conn) throw() { try { SE_LOG_DEBUG(NULL, NULL, "ForkExecParent: child %s has connected", m_helper.c_str()); m_hasConnected = true; #ifndef GDBUS_CXX_HAVE_DISCONNECT m_api.reset(new ForkExecParentDBusAPI(conn)); #endif m_onConnect(conn); } catch (...) { std::string explanation; SyncMLStatus status = Exception::handle(explanation); try { m_onFailure(status, explanation); } catch (...) { Exception::handle(); } } }
void SocketServer::run(std::mutex& mutex) { bool alive = true; while (alive) { bool performedRead = false; bool performedWrite = false; { std::lock_guard<std::mutex> m(mutex); alive = m_alive; } if (!alive) break; fd_set reader; fd_set writer; FD_ZERO(&reader); FD_ZERO(&writer); // set server socket FD_SET(m_serverSocket->m_socket, &reader); if(m_serverSocket->m_data.size() > 0) FD_SET(m_serverSocket->m_socket, &writer); // set client sockets for (auto&& sock : m_clients) { FD_SET(sock.socket->m_socket, &reader); if(sock.socket->m_data.size() > 0) //if (sock->hasData()) FD_SET(sock.socket->m_socket, &writer); } timeval time; time.tv_sec = 0; time.tv_usec = 1000; // 500 ms auto changedSockets = select(0, &reader, &writer, nullptr, &time); if (changedSockets == SOCKET_ERROR) LOG_ERROR("Socket select failed"); // check for new connections if (FD_ISSET(m_serverSocket->m_socket, &reader)) { if(!m_broadcasting) { // new connection LOG_WARNING("SocketServer got a new connection"); m_clients.emplace_back(ClientContainer{ std::make_shared<PrefixLengthMessageParser>(m_onData), std::shared_ptr<Socket>( new Socket(accept(m_serverSocket->m_socket, 0, 0)), [](Socket* ptr) { if(ptr->m_socket != INVALID_SOCKET) { closesocket(ptr->m_socket); } delete ptr; })}); SocketServer::ClientContainer& client = m_clients.back(); if (client.socket->m_socket == INVALID_SOCKET) { LOG_ERROR("Client socket failed"); m_clients.pop_back(); } else { client.parser->setSocket(client.socket); client.socket->enableSocketReuse(); client.socket->enableNoDelay(); client.socket->enableNonBlockingSocket(); if (m_onConnect) m_onConnect(client.socket); } } else { auto dataSize = m_serverSocket->dataAvailableInSocket(); if (dataSize > 0) { //LOG_INFO("got data: %i", static_cast<int>(dataSize)); std::vector<char> buffer(dataSize); auto readBytes = m_serverSocket->read(&buffer[0], dataSize); m_serverSocketParser.onData(m_serverSocket, &buffer[0], readBytes); performedRead = true; //client.parser->onData(client.socket, &buffer[0], readBytes); } } } // perform client reads/writes std::vector<ClientContainer> remove; for (auto&& client : m_clients) { if (FD_ISSET(client.socket->m_socket, &reader)) { size_t bytesRead = 0; auto dataSize = client.socket->dataAvailableInSocket(); std::vector<char> buffer(dataSize); while(bytesRead < dataSize) { //LOG_INFO("got data: %i", static_cast<int>(dataSize)); bytesRead += client.socket->read(&buffer[bytesRead], dataSize - bytesRead); performedRead = true; } ASSERT(bytesRead == dataSize, "Something went bad"); if(bytesRead > 0) client.parser->onData(client.socket, &buffer[0], bytesRead); if(dataSize == 0) { //LOG_INFO("got 0 packet"); // client disconnected remove.emplace_back(client); } } if (FD_ISSET(client.socket->m_socket, &writer)) { if(client.socket->private_write() > 0) performedWrite = true; } } /*while (remove.size() > 0) { auto sock = remove.back(); if (m_onDisconnect) m_onDisconnect(sock.socket); remove.pop_back(); for (auto iter = m_clients.begin(); iter != m_clients.end(); ++iter) { if ((*iter).socket == sock.socket) { m_clients.erase(iter); break; } } }*/ if (!performedRead && !performedWrite) { std::this_thread::sleep_for(std::chrono::milliseconds(200)); } } }