/** * @brief Function that will listen for new connections to the server sockets. * * This creates a g_socket_listener and will loop waiting for new connections until * the scheduler is closed. * * @param scheduler Relevant scheduler structure * @return (void*)0 on failure, (void*)1 on success */ void* interface_listen_thread(scheduler_t* scheduler) { GSocketListener* server_socket; GSocketConnection* new_connection; GError* error = NULL; /* validate new thread */ if(scheduler->i_terminate || !scheduler->i_created) { ERROR("Could not create server socket thread\n"); return (void*)0; } /* create the server socket to listen for connections on */ server_socket = g_socket_listener_new(); if(server_socket == NULL) FATAL("could not create the server socket"); g_socket_listener_add_inet_port(server_socket, scheduler->i_port, NULL, &error); if(error) FATAL("[port:%d]: %s", scheduler->i_port, error->message); scheduler->cancel = g_cancellable_new(); V_INTERFACE("INTERFACE: listening port is %d\n", scheduler->i_port); /* wait for new connections */ for(;;) { new_connection = g_socket_listener_accept(server_socket, NULL, scheduler->cancel, &error); if(scheduler->i_terminate) break; V_INTERFACE("INTERFACE: new interface connection\n"); if(error) FATAL("INTERFACE closing for %s", error->message); interface_conn_init(new_connection, scheduler->workers); } V_INTERFACE("INTERFACE: socket listening thread closing\n"); g_socket_listener_close(server_socket); g_object_unref(server_socket); return (void*)1; }
void GIOServiceServer::acceptThreadFunc(uint64_t threadID, GCancellable * one_thread_error_cancelable){ monitoring_namespace_protect_thread(); GSocketConnection * connection; while( (connection = g_socket_listener_accept(listener, nullptr, cancelable, nullptr)) == nullptr ){ if ( g_cancellable_is_cancelled (cancelable)){ if(connection){ g_object_unref(connection); } removeAcceptorThread(threadID); return; } } // cout << "Incoming connection" << endl; GInputStream * istream = g_io_stream_get_input_stream(G_IO_STREAM(connection)); // this spawns a response thread ServerMessageSendProcessor messageSendQueueInstance(this); messageSendQueueInstance.setProcessorQueue(new FIFOProcessorQueue()); { GOutputStream * ostream = g_io_stream_get_output_stream(G_IO_STREAM(connection)); assert ( G_IS_OUTPUT_STREAM (ostream) ); messageSendQueueInstance.connect( ostream , one_thread_error_cancelable); } // spawn another thread to accept the next connection addAcceptorThread(); // this thread now will receive messages. while( ! g_cancellable_is_cancelled(one_thread_error_cancelable) ) { uint64_t msgLength = 0; uint32_t clientSidedID = 0; CommunicationError error = CommunicationError::UNKNOWN; char * payload = readSocketMessage(istream, msgLength, clientSidedID, error, one_thread_error_cancelable); if ( payload == nullptr ){ if (msgLength > 0){ //cout << "Received broken message" << endl; messageCallback->invalidMessageReceivedCB(error); TCPClientMessage errMsg(this, clientSidedID, & messageSendQueueInstance, nullptr, 0); errMsg.isendErrorResponse(error); } break; } auto msg = shared_ptr<TCPClientMessage>(new TCPClientMessage(this, clientSidedID, & messageSendQueueInstance, payload, msgLength)); messageCallback->messageReceivedCB(msg, payload + clientMsgHeaderLen(), msgLength - clientMsgHeaderLen()); } messageSendQueueInstance.shutdown(); messageSendQueueInstance.terminate(); g_object_unref(connection); removeAcceptorThread(threadID); }