static GList * add_sources (GSocketListener *listener, GSocketSourceFunc callback, gpointer callback_data, GCancellable *cancellable, GMainContext *context) { GSocket *socket; GSource *source; GList *sources; int i; sources = NULL; for (i = 0; i < listener->priv->sockets->len; i++) { socket = listener->priv->sockets->pdata[i]; source = g_socket_create_source (socket, G_IO_IN, cancellable); g_source_set_callback (source, (GSourceFunc) callback, callback_data, NULL); g_source_attach (source, context); sources = g_list_prepend (sources, source); } return sources; }
/* Idle-handler for initial interface and address bootstrapping. * * We cannot send the RTM_GETADDR message until we processed all packets of * the RTM_GETLINK message. So on the first call this idle handler processes * all answers of RTM_GETLINK on the second call all answers of RTM_GETADDR * and on the third call it creates the regular socket source for listening on * the netlink socket, detaching itself from the idle source afterwards. */ static gboolean on_bootstrap (GUPnPLinuxContextManager *self) { if (self->priv->nl_seq == 0) { query_all_network_interfaces (self); return TRUE; } else if (self->priv->nl_seq == 1) { query_all_addresses (self); return TRUE; } else { self->priv->netlink_socket_source = g_socket_create_source (self->priv->netlink_socket, G_IO_IN | G_IO_PRI, NULL); g_source_attach (self->priv->netlink_socket_source, g_main_context_get_thread_default ()); g_source_set_callback (self->priv->netlink_socket_source, (GSourceFunc) on_netlink_message_available, self, NULL); } return FALSE; }
static void ensure_condition (GSocket *socket, const char *where, GCancellable *cancellable, GIOCondition condition) { GError *error = NULL; GSource *source; if (!non_blocking) return; if (use_source) { source = g_socket_create_source (socket, condition, cancellable); g_source_set_callback (source, (GSourceFunc) source_ready, NULL, NULL); g_source_attach (source, NULL); g_source_unref (source); g_main_loop_run (loop); } else { if (!g_socket_condition_wait (socket, condition, cancellable, &error)) { g_printerr ("condition wait error for %s: %s\n", where, error->message); exit (1); } } }
void WorkQueue::registerEventSourceHandler(int fileDescriptor, int condition, PassOwnPtr<WorkItem> item) { GRefPtr<GSocket> socket = adoptGRef(g_socket_new_from_fd(fileDescriptor, 0)); ASSERT(socket); GRefPtr<GCancellable> cancellable = adoptGRef(g_cancellable_new()); GRefPtr<GSource> dispatchSource = adoptGRef(g_socket_create_source(socket.get(), static_cast<GIOCondition>(condition), cancellable.get())); ASSERT(dispatchSource); EventSource* eventSource = new EventSource(item, this, cancellable.get()); ASSERT(eventSource); g_source_set_callback(dispatchSource.get(), reinterpret_cast<GSourceFunc>(&WorkQueue::EventSource::performWork), eventSource, reinterpret_cast<GDestroyNotify>(&WorkQueue::EventSource::deleteEventSource)); // Set up the event sources under the mutex since this is shared across multiple threads. { MutexLocker locker(m_eventSourcesLock); Vector<EventSource*> sources; EventSourceIterator it = m_eventSources.find(fileDescriptor); if (it != m_eventSources.end()) sources = it->second; sources.append(eventSource); m_eventSources.set(fileDescriptor, sources); } g_source_attach(dispatchSource.get(), m_eventContext); }
gint main (void) { gboolean ret; GSocket *socket = NULL; GSocketAddress *address = NULL; GError *error = NULL; gsize wrote; const gchar *buffer = "ping\n"; const gchar *socket_filename = "/tmp/pk-self-test.socket"; GSource *source; GMainLoop *loop; g_type_init (); loop = g_main_loop_new (NULL, FALSE); /* create socket */ socket = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, &error); if (socket == NULL) { g_warning ("failed to create socket: %s", error->message); g_error_free (error); goto out; } g_socket_set_blocking (socket, FALSE); g_socket_set_keepalive (socket, TRUE); /* connect to it */ address = g_unix_socket_address_new (socket_filename); ret = g_socket_connect (socket, address, NULL, &error); if (!ret) { g_warning ("failed to connect to socket: %s", error->message); g_error_free (error); goto out; } /* socket has data */ source = g_socket_create_source (socket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL); g_source_set_callback (source, (GSourceFunc) pk_socket_example_accept_connection_cb, loop, NULL); g_source_attach (source, NULL); /* send some data */ wrote = g_socket_send (socket, buffer, 5, NULL, &error); if (wrote != 5) { g_warning ("failed to write 5 bytes"); goto out; } /* run main loop */ g_debug ("running main loop"); g_main_loop_run (loop); out: if (loop != NULL) g_main_loop_unref (loop); if (socket != NULL) g_object_unref (socket); if (address != NULL) g_object_unref (address); return 0; }
/* Queue data starting at byte offset @message_offset from @message’s * buffers. * * Returns the message's length */ static void add_to_be_sent (NiceSocket *sock, const NiceOutputMessage *message, gsize message_offset, gsize message_len, gboolean head) { TcpPriv *priv = sock->priv; struct to_be_sent *tbs; guint j; gsize offset = 0; if (message_offset >= message_len) return; tbs = g_slice_new0 (struct to_be_sent); tbs->length = message_len - message_offset; tbs->buf = g_malloc (tbs->length); tbs->can_drop = !head; if (head) g_queue_push_head (&priv->send_queue, tbs); else g_queue_push_tail (&priv->send_queue, tbs); if (priv->io_source == NULL) { priv->io_source = g_socket_create_source(sock->fileno, G_IO_OUT, NULL); g_source_set_callback (priv->io_source, (GSourceFunc) socket_send_more, sock, NULL); g_source_attach (priv->io_source, priv->context); } /* Move the data into the buffer. */ for (j = 0; (message->n_buffers >= 0 && j < (guint) message->n_buffers) || (message->n_buffers < 0 && message->buffers[j].buffer != NULL); j++) { const GOutputVector *buffer = &message->buffers[j]; gsize len; /* Skip this buffer if it’s within @message_offset. */ if (buffer->size <= message_offset) { message_offset -= buffer->size; continue; } len = MIN (tbs->length - offset, buffer->size - message_offset); memcpy (tbs->buf + offset, (guint8 *) buffer->buffer + message_offset, len); offset += len; message_offset -= len; } }
static GSource * g_socket_output_stream_pollable_create_source (GPollableOutputStream *pollable, GCancellable *cancellable) { GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable); GSource *socket_source, *pollable_source; pollable_source = g_pollable_source_new (G_OBJECT (output_stream)); socket_source = g_socket_create_source (output_stream->priv->socket, G_IO_OUT, cancellable); g_source_set_dummy_callback (socket_source); g_source_add_child_source (pollable_source, socket_source); g_source_unref (socket_source); return pollable_source; }
static void cockpit_request_start (CockpitWebServer *self, GIOStream *io, gboolean first) { GSocketConnection *connection; CockpitRequest *request; gboolean input = TRUE; GSocket *socket; request = g_new0 (CockpitRequest, 1); request->web_server = self; request->io = g_object_ref (io); request->buffer = g_byte_array_new (); /* Right before a successive request, EOF is not unexpected */ request->eof_okay = !first; request->timeout = g_timeout_source_new_seconds (cockpit_webserver_request_timeout); g_source_set_callback (request->timeout, on_request_timeout, request, NULL); g_source_attach (request->timeout, self->main_context); if (first) { connection = G_SOCKET_CONNECTION (io); socket = g_socket_connection_get_socket (connection); g_socket_set_blocking (socket, FALSE); if (self->certificate) { request->source = g_socket_create_source (g_socket_connection_get_socket (connection), G_IO_IN, NULL); g_source_set_callback (request->source, (GSourceFunc)on_socket_input, request, NULL); g_source_attach (request->source, self->main_context); /* Wait on reading input */ input = FALSE; } } /* Owns the request */ g_hash_table_add (self->requests, request); if (input) start_request_input (request); }
void GSourceWrap::Socket::initialize(const char* name, std::function<bool (GIOCondition)>&& function, GSocket* socket, GIOCondition condition, int priority, GMainContext* context) { ASSERT(!m_source); GCancellable* cancellable = g_cancellable_new(); m_source = adoptGRef(g_socket_create_source(socket, condition, cancellable)); m_cancellable = adoptGRef(cancellable); g_source_set_name(m_source.get(), name); g_source_set_priority(m_source.get(), priority); g_source_set_callback(m_source.get(), reinterpret_cast<GSourceFunc>(staticSocketCallback), new CallbackContext{ WTF::move(function), m_cancellable }, static_cast<GDestroyNotify>(destroyCallbackContext<CallbackContext>)); if (!context) context = g_main_context_get_thread_default(); g_source_attach(m_source.get(), context); }
void dirserver_init(gchar* baseaddress) { syslog(LOG_DEBUG,"dirserver_init: starting directory server"); services = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); dirserversocket = multicast_createSocket("directoryserver", 2323, &sa); if( socket != NULL){ syslog(LOG_DEBUG,"dirserver_init: socket open"); GSource *source = g_socket_create_source(dirserversocket, G_IO_IN, NULL); ub_assert(source != NULL); g_source_set_callback(source, (GSourceFunc)dirserver_read, NULL, NULL); g_source_attach(source, g_main_context_default()); }else{ syslog(LOG_WARNING, "directory-server.c: warning: could not create socket"); } GError * e = NULL; GInetAddress *net_base = g_inet_address_new_from_string(baseaddress); if( net_base == NULL ){ syslog(LOG_ERR, "dirserver_init: Could not parse base address"); return; } //set up http tcp listener GSocketAddress *httpsa = g_inet_socket_address_new(net_base,8080); syslog(LOG_DEBUG,"dirserver_init: Creating tcp socket on port 8080\n"); GSocketService *gss = g_socket_service_new(); //TODO: save a reference to the gss somewhere if( g_socket_listener_add_address(G_SOCKET_LISTENER(gss), httpsa, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL, NULL, &e) == FALSE ){ syslog(LOG_WARNING, "dirserver_init: error while creating socket listener: %s\n",e->message); g_error_free(e); } g_signal_connect(gss, "incoming", G_CALLBACK(dirserver_tcp_listener),NULL); g_socket_service_start(gss); g_timeout_add_seconds(1,dirserver_tick,NULL); }
static gboolean on_new_connection (GSocketService *service, GSocketConnection *socket_connection, GObject *source_object, DasomServer *server) { g_debug (G_STRLOC ": %s", G_STRFUNC); /* TODO: simple authentication using GCredentials */ GSocket *socket = g_socket_connection_get_socket (socket_connection); DasomMessage *message; message = dasom_recv_message (socket); if (message->header->type == DASOM_MESSAGE_CONNECT) dasom_send_message (socket, DASOM_MESSAGE_CONNECT_REPLY, NULL, 0, NULL); else { /* TODO: error handling */ dasom_send_message (socket, DASOM_MESSAGE_ERROR, NULL, 0, NULL); return TRUE; /* TODO: what happened if return value is FALSE */ } DasomConnection *connection; connection = dasom_connection_new (*(DasomConnectionType *) message->data, dasom_server_get_default_engine (server), NULL); dasom_message_unref (message); connection->socket = socket; dasom_server_add_connection (server, connection); if (connection->type == DASOM_CONNECTION_DASOM_AGENT) server->agents_list = g_list_prepend (server->agents_list, connection); connection->source = g_socket_create_source (socket, G_IO_IN, NULL); connection->socket_connection = g_object_ref (socket_connection); g_source_set_can_recurse (connection->source, TRUE); g_source_set_callback (connection->source, (GSourceFunc) on_incoming_message_dasom, connection, NULL); g_source_attach (connection->source, server->main_context); return TRUE; }
/* Must *not* take the agent lock, since it’s called from within * component_set_io_context(), which holds the Component’s I/O lock. */ static void socket_source_attach (SocketSource *socket_source, GMainContext *context) { GSource *source; /* Create a source. */ source = g_socket_create_source (socket_source->socket->fileno, G_IO_IN, NULL); g_source_set_callback (source, (GSourceFunc) component_io_cb, socket_source, NULL); /* Add the source. */ nice_debug ("Attaching source %p (socket %p, FD %d) to context %p", source, socket_source->socket, g_socket_get_fd (socket_source->socket->fileno), context); g_assert (socket_source->source == NULL); socket_source->source = source; g_source_attach (source, context); }
void GMainLoopSource::schedule(const char* name, std::function<bool (GIOCondition)> function, GSocket* socket, GIOCondition condition, std::function<void ()> destroyFunction, GMainContext* context) { cancel(); ASSERT(!m_context.source); GCancellable* socketCancellable = g_cancellable_new(); m_context = { adoptGRef(g_socket_create_source(socket, condition, socketCancellable)), nullptr, // cancellable adoptGRef(socketCancellable), nullptr, // voidCallback nullptr, // boolCallback WTF::move(function), WTF::move(destroyFunction) }; ASSERT(m_status == Ready); m_status = Scheduled; g_source_set_name(m_context.source.get(), name); g_source_set_callback(m_context.source.get(), reinterpret_cast<GSourceFunc>(socketSourceCallback), this, nullptr); g_source_attach(m_context.source.get(), context); }
static gboolean net_createUDPSocket(struct node *n, guint classid) { GError * err = NULL; GInetAddress *addr = n->netadr; guint port = 2300+n->classes[classid]; syslog(LOG_DEBUG,"net_createSockets: Creating udp socket on port %u\n", port); GSocketAddress * sa = g_inet_socket_address_new(addr,port); n->udpsockets[classid].n = n; GSocket *socket = g_socket_new(G_SOCKET_FAMILY_IPV6, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, NULL); ub_assert(socket != NULL); if( g_socket_bind(socket, sa, TRUE, &err) == FALSE ){ syslog(LOG_WARNING, "net_createSockets: Error while binding udp socket: %s\n", err->message); g_error_free(err); return FALSE; } GSource *source = g_socket_create_source(socket, G_IO_IN, NULL); ub_assert(source != NULL); g_source_set_callback(source, (GSourceFunc)udp_read, &(n->udpsockets[classid]) , NULL); g_source_attach(source, g_main_context_default()); n->udpsockets[classid].socket = socket; n->udpsockets[classid].source = source; n->udpsockets[classid].socketaddress = sa; n->udpsockets[classid].classid = classid; //broadcast_addService(n->classes[classid]); return TRUE; }
static gboolean fusion_tls_output_stream_real_write_async_co (FusionTlsOutputStreamWriteAsyncData* _data_) { switch (_data_->_state_) { case 0: goto _state_0; case 1: goto _state_1; default: g_assert_not_reached (); } _state_0: _data_->_tmp0_ = NULL; _data_->_tmp0_ = _data_->self->priv->socket; _data_->_tmp1_ = 0; _data_->_tmp1_ = g_socket_condition_check (_data_->_tmp0_, G_IO_OUT); if (_data_->_tmp1_ == 0) { _data_->_tmp2_ = NULL; _data_->_tmp2_ = _data_->self->priv->socket; _data_->_tmp3_ = NULL; _data_->_tmp3_ = _data_->cancellable; _data_->_tmp4_ = NULL; _data_->_tmp4_ = g_socket_create_source (_data_->_tmp2_, (G_IO_OUT | G_IO_HUP) | G_IO_ERR, _data_->_tmp3_); _data_->source = _data_->_tmp4_; _data_->_tmp5_ = NULL; _data_->_tmp5_ = _data_->source; g_source_set_callback (_data_->_tmp5_, (GSourceFunc) _fusion_tls_output_stream_real_write_async_co_gsocket_source_func, _data_, NULL); _data_->_tmp6_ = NULL; _data_->_tmp6_ = _data_->source; _data_->_tmp7_ = NULL; _data_->_tmp7_ = g_main_context_get_thread_default (); g_source_attach (_data_->_tmp6_, _data_->_tmp7_); _data_->_state_ = 1; return FALSE; _state_1: ; _g_source_unref0 (_data_->source); } _data_->_tmp9_ = NULL; _data_->_tmp9_ = _data_->self->priv->connection; _data_->_tmp10_ = NULL; _data_->_tmp10__length1 = 0; _data_->_tmp10_ = _data_->buffer; _data_->_tmp10__length1 = _data_->buffer_length1; _data_->_tmp11_ = NULL; _data_->_tmp11_ = _data_->cancellable; _data_->_tmp12_ = 0L; _data_->_tmp12_ = fusion_tls_connection_send (_data_->_tmp9_, _data_->_tmp10_, _data_->_tmp10__length1, _data_->_tmp11_, &_data_->_inner_error_); _data_->_tmp8_ = _data_->_tmp12_; if (_data_->_inner_error_ != NULL) { if (_data_->_inner_error_->domain == G_IO_ERROR) { g_simple_async_result_set_from_error (_data_->_async_result, _data_->_inner_error_); g_error_free (_data_->_inner_error_); if (_data_->_state_ == 0) { g_simple_async_result_complete_in_idle (_data_->_async_result); } else { g_simple_async_result_complete (_data_->_async_result); } g_object_unref (_data_->_async_result); return FALSE; } else { g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _data_->_inner_error_->message, g_quark_to_string (_data_->_inner_error_->domain), _data_->_inner_error_->code); g_clear_error (&_data_->_inner_error_); return FALSE; } } _data_->result = _data_->_tmp8_; if (_data_->_state_ == 0) { g_simple_async_result_complete_in_idle (_data_->_async_result); } else { g_simple_async_result_complete (_data_->_async_result); } g_object_unref (_data_->_async_result); return FALSE; if (_data_->_state_ == 0) { g_simple_async_result_complete_in_idle (_data_->_async_result); } else { g_simple_async_result_complete (_data_->_async_result); } g_object_unref (_data_->_async_result); return FALSE; }
static void _channel_accepted (TpChannel *channel, const GValue *addressv, const GError *in_error, gpointer user_data, GObject *obj) { TpStreamTubeChannel *self = (TpStreamTubeChannel *) obj; GSocketAddress *remote_address; GError *error = NULL; if (in_error != NULL) { DEBUG ("Failed to Accept Stream Tube: %s", in_error->message); operation_failed (self, in_error); return; } tp_cli_channel_type_stream_tube_connect_to_new_local_connection ( TP_CHANNEL (self), new_local_connection_cb, NULL, NULL, G_OBJECT (self), &error); if (error != NULL) { DEBUG ("Failed to connect to NewLocalConnection signal"); operation_failed (self, error); g_error_free (error); return; } remote_address = tp_g_socket_address_from_variant (self->priv->socket_type, addressv, &error); if (error != NULL) { DEBUG ("Failed to convert address: %s", error->message); operation_failed (self, error); g_error_free (error); return; } /* Connect to CM */ g_socket_set_blocking (self->priv->client_socket, FALSE); g_socket_connect (self->priv->client_socket, remote_address, NULL, &error); if (error == NULL) { /* Socket is connected */ client_socket_connected (self); goto out; } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PENDING)) { /* We have to wait that the socket is connected */ GSource *source; source = g_socket_create_source (self->priv->client_socket, G_IO_OUT, NULL); g_source_attach (source, g_main_context_get_thread_default ()); g_source_set_callback (source, (GSourceFunc) client_socket_cb, self, NULL); g_error_free (error); g_source_unref (source); } else { DEBUG ("Failed to connect to CM: %s", error->message); operation_failed (self, error); g_error_free (error); } out: g_object_unref (remote_address); }
static void dasom_im_init (DasomIM *im) { g_debug (G_STRLOC ": %s", G_STRFUNC); GSocketClient *client; GSocketAddress *address; GSocket *socket; GError *error = NULL; address = g_unix_socket_address_new_with_type (DASOM_ADDRESS, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); client = g_socket_client_new (); im->connection = g_socket_client_connect (client, G_SOCKET_CONNECTABLE (address), NULL, &error); g_object_unref (address); g_object_unref (client); if (im->connection == NULL) { g_critical (G_STRLOC ": %s: %s", G_STRFUNC, error->message); g_clear_error (&error); return; } socket = g_socket_connection_get_socket (im->connection); if (!socket) { g_critical (G_STRLOC ": %s: %s", G_STRFUNC, "Can't get socket"); return; } DasomMessage *message; DasomConnectionType type = DASOM_CONNECTION_DASOM_IM; dasom_send_message (socket, DASOM_MESSAGE_CONNECT, &type, sizeof (DasomConnectionType), NULL); g_socket_condition_wait (socket, G_IO_IN, NULL, NULL); message = dasom_recv_message (socket); if (G_UNLIKELY (message == NULL || message->header->type != DASOM_MESSAGE_CONNECT_REPLY)) { dasom_message_unref (message); g_error ("Couldn't connect to dasom daemon"); } dasom_message_unref (message); im->result = g_slice_new0 (DasomResult); im->preedit_string = g_strdup (""); GMutex mutex; g_mutex_init (&mutex); g_mutex_lock (&mutex); if (G_UNLIKELY (dasom_im_sockets_context == NULL)) { dasom_im_sockets_context = g_main_context_new (); dasom_im_sockets_context_ref_count++; } else { dasom_im_sockets_context = g_main_context_ref (dasom_im_sockets_context); dasom_im_sockets_context_ref_count++; } g_mutex_unlock (&mutex); /* when g_main_context_iteration(), iterate only sockets */ im->sockets_context_source = g_socket_create_source (socket, G_IO_IN, NULL); g_source_set_can_recurse (im->sockets_context_source, TRUE); g_source_attach (im->sockets_context_source, dasom_im_sockets_context); g_source_set_callback (im->sockets_context_source, (GSourceFunc) on_incoming_message, im, NULL); im->default_context_source = g_socket_create_source (socket, G_IO_IN, NULL); g_source_set_can_recurse (im->default_context_source, TRUE); g_source_set_callback (im->default_context_source, (GSourceFunc) on_incoming_message, im, NULL); g_source_attach (im->default_context_source, NULL); }
static gboolean component_source_prepare (GSource *source, gint *timeout_) { ComponentSource *component_source = (ComponentSource *) source; NiceAgent *agent; NiceComponent *component; GSList *parentl, *childl; agent = g_weak_ref_get (&component_source->agent_ref); if (!agent) return FALSE; /* Needed due to accessing the Component. */ agent_lock (); if (!agent_find_component (agent, component_source->stream_id, component_source->component_id, NULL, &component)) goto done; if (component->socket_sources_age == component_source->component_socket_sources_age) goto done; /* If the age has changed, either * - one or more new socket has been prepended * - old sockets have been removed */ /* Add the new child sources. */ for (parentl = component->socket_sources; parentl; parentl = parentl->next) { SocketSource *parent_socket_source = parentl->data; SocketSource *child_socket_source; if (parent_socket_source->socket->fileno == NULL) continue; /* Iterating the list of socket sources every time isn't a big problem * because the number of pairs is limited ~100 normally, so there will * rarely be more than 10. */ childl = g_slist_find_custom (component_source->socket_sources, parent_socket_source->socket, _find_socket_source); /* If we have reached this state, then all sources new sources have been * added, because they are always prepended. */ if (childl) break; child_socket_source = g_slice_new0 (SocketSource); child_socket_source->socket = parent_socket_source->socket; child_socket_source->source = g_socket_create_source (child_socket_source->socket->fileno, G_IO_IN, NULL); g_source_set_dummy_callback (child_socket_source->source); g_source_add_child_source (source, child_socket_source->source); g_source_unref (child_socket_source->source); component_source->socket_sources = g_slist_prepend (component_source->socket_sources, child_socket_source); } for (childl = component_source->socket_sources; childl;) { SocketSource *child_socket_source = childl->data; GSList *next = childl->next; parentl = g_slist_find_custom (component->socket_sources, child_socket_source->socket, _find_socket_source); /* If this is not a currently used socket, remove the relevant source */ if (!parentl) { g_source_remove_child_source (source, child_socket_source->source); g_slice_free (SocketSource, child_socket_source); component_source->socket_sources = g_slist_delete_link (component_source->socket_sources, childl); } childl = next; } /* Update the age. */ component_source->component_socket_sources_age = component->socket_sources_age; done: agent_unlock_and_emit (agent); g_object_unref (agent); /* We can’t be sure if the ComponentSource itself needs to be dispatched until * poll() is called on all the child sources. */ return FALSE; }
static gboolean g_network_monitor_netlink_initable_init (GInitable *initable, GCancellable *cancellable, GError **error) { GNetworkMonitorNetlink *nl = G_NETWORK_MONITOR_NETLINK (initable); gint sockfd, val; struct sockaddr_nl snl; /* We create the socket the old-school way because sockaddr_netlink * can't be represented as a GSocketAddress */ sockfd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sockfd == -1) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); return FALSE; } snl.nl_family = AF_NETLINK; snl.nl_pid = snl.nl_pad = 0; snl.nl_groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE; if (bind (sockfd, (struct sockaddr *)&snl, sizeof (snl)) != 0) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); close (sockfd); return FALSE; } val = 1; if (setsockopt (sockfd, SOL_SOCKET, SO_PASSCRED, &val, sizeof (val)) != 0) { int errsv = errno; g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv), _("Could not create network monitor: %s"), g_strerror (errno)); close (sockfd); return FALSE; } nl->priv->sock = g_socket_new_from_fd (sockfd, error); if (error) { g_prefix_error (error, "%s", _("Could not create network monitor: ")); close (sockfd); return FALSE; } /* Request the current state */ if (!request_dump (nl, error)) return FALSE; /* And read responses; since we haven't yet marked the socket * non-blocking, each call will block until a message is received. */ while (nl->priv->dump_networks) { if (!read_netlink_messages (NULL, G_IO_IN, nl)) break; } g_socket_set_blocking (nl->priv->sock, FALSE); nl->priv->source = g_socket_create_source (nl->priv->sock, G_IO_IN, NULL); g_source_set_callback (nl->priv->source, (GSourceFunc) read_netlink_messages, nl, NULL); g_source_attach (nl->priv->source, g_main_context_get_thread_default ()); return TRUE; }
static gboolean gssdp_socket_source_do_init (GInitable *initable, G_GNUC_UNUSED GCancellable *cancellable, GError **error) { GSSDPSocketSource *self = NULL; GInetAddress *iface_address = NULL; GSocketAddress *bind_address = NULL; GInetAddress *group = NULL; GError *inner_error = NULL; GSocketFamily family; gboolean success = FALSE; self = GSSDP_SOCKET_SOURCE (initable); iface_address = g_inet_address_new_from_string (self->priv->host_ip); if (iface_address == NULL) { g_set_error (error, GSSDP_ERROR, GSSDP_ERROR_FAILED, "Invalid host ip: %s", self->priv->host_ip); goto error; } family = g_inet_address_get_family (iface_address); if (family == G_SOCKET_FAMILY_IPV4) group = g_inet_address_new_from_string (SSDP_ADDR); else { g_set_error_literal (error, GSSDP_ERROR, GSSDP_ERROR_FAILED, "IPv6 address"); goto error; } /* Create socket */ self->priv->socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_DATAGRAM, G_SOCKET_PROTOCOL_UDP, &inner_error); if (!self->priv->socket) { g_propagate_prefixed_error (error, inner_error, "Could not create socket"); goto error; } /* Enable broadcasting */ if (!gssdp_socket_enable_broadcast (self->priv->socket, TRUE, &inner_error)) { g_propagate_prefixed_error (error, inner_error, "Failed to enable broadcast"); goto error; } /* TTL */ if (!self->priv->ttl) /* UDA/1.0 says 4, UDA/1.1 says 2 */ self->priv->ttl = 4; if (!gssdp_socket_set_ttl (self->priv->socket, self->priv->ttl, &inner_error)) { g_propagate_prefixed_error (error, inner_error, "Failed to set TTL to %u", self->priv->ttl); goto error; } /* Set up additional things according to the type of socket desired */ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) { /* Enable multicast loopback */ if (!gssdp_socket_enable_loop (self->priv->socket, TRUE, &inner_error)) { g_propagate_prefixed_error ( error, inner_error, "Failed to enable loop-back"); goto error; } if (!gssdp_socket_mcast_interface_set (self->priv->socket, iface_address, &inner_error)) { g_propagate_prefixed_error ( error, inner_error, "Failed to set multicast interface"); goto error; } #ifdef G_OS_WIN32 bind_address = g_inet_socket_address_new (iface_address, SSDP_PORT); #else bind_address = g_inet_socket_address_new (group, SSDP_PORT); #endif } else { guint port = SSDP_PORT; /* Use user-supplied or random port for the socket source used * by M-SEARCH */ if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_SEARCH) port = self->priv->port; bind_address = g_inet_socket_address_new (iface_address, port); } /* Normally g_socket_bind does this, but it is disabled on * windows since SO_REUSEADDR has different semantics * there, also we nees SO_REUSEPORT on OpenBSD. This is a nop * everywhere else. */ if (!gssdp_socket_reuse_address (self->priv->socket, TRUE, &inner_error)) { g_propagate_prefixed_error ( error, inner_error, "Failed to enable reuse"); goto error; } /* Bind to requested port and address */ if (!g_socket_bind (self->priv->socket, bind_address, TRUE, &inner_error)) { g_propagate_prefixed_error (error, inner_error, "Failed to bind socket"); goto error; } if (self->priv->type == GSSDP_SOCKET_SOURCE_TYPE_MULTICAST) { /* Subscribe to multicast channel */ if (!gssdp_socket_mcast_group_join (self->priv->socket, group, iface_address, &inner_error)) { char *address = g_inet_address_to_string (group); g_propagate_prefixed_error (error, inner_error, "Failed to join group %s", address); g_free (address); goto error; } } self->priv->source = g_socket_create_source (self->priv->socket, G_IO_IN | G_IO_ERR, NULL); success = TRUE; error: if (iface_address != NULL) g_object_unref (iface_address); if (bind_address != NULL) g_object_unref (bind_address); if (group != NULL) g_object_unref (group); if (!success) /* Be aware that inner_error has already been free'd by * g_propagate_error(), so we cannot access its contents * anymore. */ if (error == NULL) g_warning ("Failed to create socket source"); return success; }
static gpointer gst_net_client_clock_thread (gpointer data) { GstNetClientClock *self = data; GstNetTimePacket *packet; GMainContext *ctx; GSourceFuncs funcs = { NULL, }; GSource *source; GIOCondition cond; gboolean timeout; GSocket *socket = self->priv->socket; GError *err = NULL; GstClock *clock = data; GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket); g_socket_set_blocking (socket, TRUE); g_socket_set_timeout (socket, 0); ctx = g_main_context_new (); source = g_socket_create_source (socket, G_IO_IN, self->priv->cancel); g_source_set_name (source, "GStreamer net client clock thread socket"); g_source_set_callback (source, (GSourceFunc) gst_net_client_clock_socket_cb, &cond, NULL); g_source_attach (source, ctx); g_source_unref (source); /* GSocket only support second granularity for timeouts, so roll our own * timeout source (so we don't have to create a new source whenever the * timeout changes, as we would have to do with the default timeout source) */ funcs.prepare = gst_net_client_clock_timeout_source_prepare; funcs.check = gst_net_client_clock_timeout_source_check; funcs.dispatch = gst_net_client_clock_timeout_source_dispatch; funcs.finalize = NULL; source = g_source_new (&funcs, sizeof (GstNetClientClockTimeoutSource)); ((GstNetClientClockTimeoutSource *) source)->clock = self; ((GstNetClientClockTimeoutSource *) source)->p_timeout = &timeout; g_source_set_name (source, "GStreamer net client clock timeout"); g_source_attach (source, ctx); g_source_unref (source); while (!g_cancellable_is_cancelled (self->priv->cancel)) { cond = 0; timeout = FALSE; g_main_context_iteration (ctx, TRUE); if (g_cancellable_is_cancelled (self->priv->cancel)) break; if (timeout) { /* timed out, let's send another packet */ GST_DEBUG_OBJECT (self, "timed out"); packet = gst_net_time_packet_new (NULL); packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); gst_net_time_packet_send (packet, self->priv->socket, self->priv->servaddr, NULL); g_free (packet); /* reset timeout (but are expecting a response sooner anyway) */ self->priv->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (clock); continue; } /* got data to read? */ if ((cond & G_IO_IN)) { GstClockTime new_local; new_local = gst_clock_get_internal_time (GST_CLOCK (self)); packet = gst_net_time_packet_receive (socket, NULL, &err); if (err != NULL) { GST_WARNING_OBJECT (self, "receive error: %s", err->message); g_error_free (err); err = NULL; continue; } GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->remote_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); /* observe_times will reset the timeout */ gst_net_client_clock_observe_times (self, packet->local_time, packet->remote_time, new_local); g_free (packet); continue; } if ((cond & (G_IO_ERR | G_IO_HUP))) { GST_DEBUG_OBJECT (self, "socket error?! %s", g_strerror (errno)); g_usleep (G_USEC_PER_SEC / 10); continue; } } GST_INFO_OBJECT (self, "shutting down net client clock thread"); g_main_context_unref (ctx); return NULL; }
int main(void) { GSocket *sock; sock = create_socket(); committed = g_string_new(""); puts("Emacs-fcitx is ready."); while (TRUE) { GSource *source; GSocket *connection; GMainLoop *main_loop; if ((connection = g_socket_accept(sock, NULL, NULL)) == NULL) { perror("g_socket_accept"); exit(1); } puts("Opening connection."); client = fcitx_client_new(); g_signal_connect(client, "connected", G_CALLBACK(connect_cb), NULL); g_signal_connect(client, "disconnected", G_CALLBACK(destroy_cb), NULL); g_signal_connect(client, "enable-im", G_CALLBACK(enable_im_cb), NULL); g_signal_connect(client, "close-im", G_CALLBACK(close_im_cb), NULL); g_signal_connect(client, "forward-key", G_CALLBACK(forward_key_cb), NULL); g_signal_connect(client, "commit-string", G_CALLBACK(commit_string_cb), NULL); g_signal_connect(client, "update-client-side-ui", G_CALLBACK(update_client_side_ui_cb), connection); main_loop = g_main_loop_new(NULL, FALSE); source = g_socket_create_source( connection, (GIOCondition)(G_IO_IN | G_IO_HUP | G_IO_ERR), NULL); g_source_set_callback( source, (GSourceFunc)source_cb, main_loop, NULL); g_source_attach(source, NULL); g_main_loop_run(main_loop); puts("main loop finished."); g_socket_close(connection, NULL); g_object_unref(client); g_source_unref(source); g_object_unref(connection); g_main_loop_unref(main_loop); } g_object_unref(sock); g_string_free(committed, TRUE); return 0; }
int init_netlink(GMainLoop *loop) { GSocket *gsocket = NULL; int socket_fd = 0; GSource *source; struct sockaddr_nl my_nla; struct nlmsghdr *nl_hdr; char buff[BUFF_SIZE]; struct cn_msg *cn_hdr; enum proc_cn_mcast_op *mcop_msg; /* create socket */ /* * Create an endpoint for communication. Use the kernel user * interface device (PF_NETLINK) which is a datagram oriented * service (SOCK_DGRAM). The protocol used is the connector * protocol (NETLINK_CONNECTOR) */ socket_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); if (socket_fd == -1) { g_warning ("netlink: failed to create socket: %s", g_strerror(errno)); return 1; } my_nla.nl_family = AF_NETLINK; my_nla.nl_groups = CN_IDX_PROC; my_nla.nl_pid = getpid(); my_nla.nl_pad = 0; if (bind(socket_fd, (struct sockaddr *)&my_nla, sizeof(my_nla)) < 0) { g_warning("netlink: binding sk_nl error: %s\n", g_strerror(errno)); g_warning("netlink: realtime monitoring disabled. compile kernel with PROC_EVENTS enabled"); goto out; } gsocket = g_socket_new_from_fd(socket_fd, NULL); if(gsocket == NULL) { g_warning("netlink: can't create socket"); goto out; } nl_hdr = (struct nlmsghdr *)buff; cn_hdr = (struct cn_msg *)NLMSG_DATA(nl_hdr); mcop_msg = (enum proc_cn_mcast_op*)&cn_hdr->data[0]; g_debug("netlink: sending proc connector: PROC_CN_MCAST_LISTEN... "); memset(buff, 0, sizeof(buff)); *mcop_msg = PROC_CN_MCAST_LISTEN; /* test if PROC_CN_MCAST_LISTEN will success */ netlink_proc_listening = FALSE; g_socket_set_timeout(gsocket, 10); /* fill the netlink header */ nl_hdr->nlmsg_len = SEND_MESSAGE_LEN; nl_hdr->nlmsg_type = NLMSG_DONE; nl_hdr->nlmsg_flags = 0; nl_hdr->nlmsg_seq = 0; nl_hdr->nlmsg_pid = getpid(); /* fill the connector header */ cn_hdr->id.idx = CN_IDX_PROC; cn_hdr->id.val = CN_VAL_PROC; cn_hdr->seq = 0; cn_hdr->ack = 0; cn_hdr->len = sizeof(enum proc_cn_mcast_op); g_debug("netlink: sending netlink message len=%d, cn_msg len=%d\n", nl_hdr->nlmsg_len, (int) sizeof(struct cn_msg)); if (send(socket_fd, nl_hdr, nl_hdr->nlmsg_len, 0) != nl_hdr->nlmsg_len) { g_warning("netlink: failed to send proc connector mcast ctl op!: %s\n", g_strerror(errno)); } g_debug("sent\n"); /* socket has data */ source = g_socket_create_source (gsocket, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, NULL); g_source_set_callback (source, (GSourceFunc) nl_connection_handler, loop, NULL); g_source_attach (source, NULL); return 0; out: return 1; }