static GSource * watch_attr (UDisksLinuxDevice *device, const gchar *attr, GSourceFunc callback, gpointer user_data) { GError *error = NULL; gchar *path = NULL; GIOChannel *channel = NULL; GSource *ret = NULL;; g_return_val_if_fail (UDISKS_IS_LINUX_DEVICE (device), NULL); path = g_strdup_printf ("%s/%s", g_udev_device_get_sysfs_path (device->udev_device), attr); channel = g_io_channel_new_file (path, "r", &error); if (channel != NULL) { ret = g_io_create_watch (channel, G_IO_ERR); g_source_set_callback (ret, callback, user_data, NULL); g_source_attach (ret, g_main_context_get_thread_default ()); g_source_unref (ret); g_io_channel_unref (channel); /* the keeps a reference to this object */ } else { udisks_warning ("Error creating watch for file %s: %s (%s, %d)", path, error->message, g_quark_to_string (error->domain), error->code); g_clear_error (&error); } g_free (path); return ret; }
/* IN EVENT OR INVOKE THREAD */ static void hrt_watcher_io_start(HrtWatcher *watcher) { HrtWatcherGLib *gwatcher = (HrtWatcherGLib*) watcher; HrtWatcherIo *io_watcher = (HrtWatcherIo*) watcher; if (gwatcher->source == NULL) { GSource *source; source = g_io_create_watch(io_watcher->channel, io_watcher->condition); _hrt_watcher_ref(watcher); g_source_set_callback(source, (GSourceFunc) run_watcher_io_func, watcher, watcher_dnotify); gwatcher->source = source; /* takes the ref */ /* When we attach the source, we're addding it to the event * thread, and it can IMMEDIATELY RUN so from here, the * watcher is subject to re-entrancy even on initial * construct. */ g_source_attach(source, hrt_watcher_get_g_main_context(watcher)); } }
static void create_child (void) { GError *err; GIOChannel *in_channels[2]; GIOChannel *out_channels[2]; GIOChannel **sub_channels; GSource *source; sub_channels = g_new (GIOChannel *, 2); io_pipe (in_channels); io_pipe (out_channels); sub_channels[0] = in_channels[0]; sub_channels[1] = out_channels[1]; source = g_io_create_watch (out_channels[0], G_IO_IN | G_IO_HUP); g_assert(source != NULL); g_source_set_closure (source, g_cclosure_new (G_CALLBACK (input_callback), in_channels[1], NULL)); g_source_attach (source, NULL); g_thread_create(run_child,sub_channels,FALSE,&err); }
static gboolean attach_fifo(const char *name) { GSource *source; int fd = open (name, O_RDONLY|O_NONBLOCK); if (fd == -1) return FALSE; if (fifo_channel) g_io_channel_unref(fifo_channel); fifo_channel = g_io_channel_unix_new(fd); g_io_channel_set_flags(fifo_channel, G_IO_FLAG_NONBLOCK, NULL); g_io_channel_set_encoding(fifo_channel, NULL, NULL); g_io_channel_set_close_on_unref(fifo_channel, TRUE); source = g_io_create_watch(fifo_channel, G_IO_IN|G_IO_PRI|G_IO_ERR|G_IO_HUP|G_IO_NVAL); g_source_set_callback(source, (GSourceFunc)fifo_callback, (gpointer)fifo_channel, (GDestroyNotify)fifo_destroy_callback); g_source_attach(source, main_context); return TRUE; }
/** * gst_rtsp_server_create_watch: * @server: a #GstRTSPServer * * Create a #GSource for @server. The new source will have a default * #GIOFunc of gst_rtsp_server_io_func(). * * Returns: the #GSource for @server or NULL when an error occured. */ GSource * gst_rtsp_server_create_watch (GstRTSPServer * server) { GIOChannel *channel; GSource *source; g_return_val_if_fail (GST_IS_RTSP_SERVER (server), NULL); channel = gst_rtsp_server_get_io_channel (server); if (channel == NULL) goto no_channel; /* create a watch for reads (new connections) and possible errors */ source = g_io_create_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); g_io_channel_unref (channel); /* configure the callback */ g_source_set_callback (source, (GSourceFunc) gst_rtsp_server_io_func, g_object_ref (server), (GDestroyNotify) watch_destroyed); return source; no_channel: { GST_ERROR_OBJECT (server, "failed to create IO channel"); return NULL; } }
/* * ajax_worker_run */ gpointer ajax_worker_run ( ajax_worker *aw ) { log_print ( "ajax-%u: worker entering event loop.\n", aw->uid ); /* spawn main loop driver */ aw->context = g_main_context_new ( ); aw->mainloop = g_main_loop_new ( aw->context, FALSE ); g_main_context_push_thread_default ( aw->context ); /* attach socket */ if ( listen(aw->server_socket, AJAX_QUEUE_SIZE) != 0 ) { log_print ( "ajax-%u: unable to listen on socket: %s", aw->uid, strerror(errno) ); return NULL; } aw->server_chan = g_io_channel_unix_new ( aw->server_socket ); aw->server_src = g_io_create_watch ( aw->server_chan, G_IO_IN ); g_source_set_callback ( aw->server_src, (GSourceFunc)handle_new_connection, aw, NULL ); g_source_attach ( aw->server_src, aw->context ); /* enter main loop */ aw->nb_requests = 0; g_timeout_add_seconds ( 60, (GSourceFunc)handle_alive_timeout, aw ); g_main_loop_run ( aw->mainloop ); return NULL; }
void YapServer::init() { struct sockaddr_un socketAddr; d->socketFd = ::socket(PF_LOCAL, SOCK_STREAM, 0); if (d->socketFd < 0) { fprintf(stderr, "YAP: Failed to create socket: %s\n", strerror(errno)); return; } socketAddr.sun_family = AF_LOCAL; ::strncpy(socketAddr.sun_path, d->socketPath, G_N_ELEMENTS(socketAddr.sun_path)); socketAddr.sun_path[G_N_ELEMENTS(socketAddr.sun_path)-1] = '\0'; if (::bind(d->socketFd, (struct sockaddr*) &socketAddr, SUN_LEN(&socketAddr)) != 0) { fprintf(stderr, "YAP: Failed to bind socket: %s\n", strerror(errno)); d->socketFd = -1; return; } if (::listen(d->socketFd, kMaxConnections) != 0) { fprintf(stderr, "YAP: Failed to listen on socket: %s\n", strerror(errno)); d->socketFd = -1; return; } d->mainCtxt = g_main_context_default(); d->mainLoop = g_main_loop_new(d->mainCtxt, TRUE); d->ioChannel = g_io_channel_unix_new(d->socketFd); d->ioSource = g_io_create_watch(d->ioChannel, (GIOCondition) (G_IO_IN | G_IO_HUP)); g_source_set_callback(d->ioSource, (GSourceFunc) YapServerPriv::ioCallback, this, NULL); g_source_attach(d->ioSource, d->mainCtxt); }
void WorkQueue::registerEventSourceHandler(int fileDescriptor, int condition, PassOwnPtr<WorkItem> item) { GIOChannel* channel = g_io_channel_unix_new(fileDescriptor); ASSERT(channel); GSource* dispatchSource = g_io_create_watch(channel, static_cast<GIOCondition>(condition)); ASSERT(dispatchSource); EventSource* eventSource = new EventSource(dispatchSource, item, this); ASSERT(eventSource); g_source_set_callback(dispatchSource, 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); ASSERT(!m_eventSources.contains(fileDescriptor)); 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); } // Attach the event source to the GMainContext under the mutex since this is shared across multiple threads. { MutexLocker locker(m_eventLoopLock); g_source_attach(dispatchSource, m_eventContext); } }
/** * Put a message in the queue awaiting to be sent to the client. * Should hold client->lock. */ static gboolean xmms_ipc_client_msg_write (xmms_ipc_client_t *client, xmms_ipc_msg_t *msg) { gboolean queue_empty; g_return_val_if_fail (client, FALSE); g_return_val_if_fail (msg, FALSE); queue_empty = g_queue_is_empty (client->out_msg); g_queue_push_tail (client->out_msg, msg); /* If there's no write in progress, add a new callback */ if (queue_empty) { GMainContext *context = g_main_loop_get_context (client->ml); GSource *source = g_io_create_watch (client->iochan, G_IO_OUT); g_source_set_callback (source, (GSourceFunc) xmms_ipc_client_write_cb, (gpointer) client, NULL); g_source_attach (source, context); g_source_unref (source); g_main_context_wakeup (context); } return TRUE; }
nsresult nsAppShell::Init() { #ifdef PR_LOGGING if (!gWidgetLog) gWidgetLog = PR_NewLogModule("Widget"); if (!gWidgetFocusLog) gWidgetFocusLog = PR_NewLogModule("WidgetFocus"); if (!gWidgetDragLog) gWidgetDragLog = PR_NewLogModule("WidgetDrag"); if (!gWidgetDrawLog) gWidgetDrawLog = PR_NewLogModule("WidgetDraw"); #endif if (!sPollFunc) { sPollFunc = g_main_context_get_poll_func(NULL); g_main_context_set_poll_func(NULL, &PollWrapper); } if (PR_GetEnv("MOZ_DEBUG_PAINTS")) gdk_window_set_debug_updates(TRUE); int err = pipe(mPipeFDs); if (err) return NS_ERROR_OUT_OF_MEMORY; GIOChannel *ioc; GSource *source; // make the pipe nonblocking int flags = fcntl(mPipeFDs[0], F_GETFL, 0); if (flags == -1) goto failed; err = fcntl(mPipeFDs[0], F_SETFL, flags | O_NONBLOCK); if (err == -1) goto failed; flags = fcntl(mPipeFDs[1], F_GETFL, 0); if (flags == -1) goto failed; err = fcntl(mPipeFDs[1], F_SETFL, flags | O_NONBLOCK); if (err == -1) goto failed; ioc = g_io_channel_unix_new(mPipeFDs[0]); source = g_io_create_watch(ioc, G_IO_IN); g_io_channel_unref(ioc); g_source_set_callback(source, (GSourceFunc)EventProcessorCallback, this, nullptr); g_source_set_can_recurse(source, TRUE); mTag = g_source_attach(source, nullptr); g_source_unref(source); return nsBaseAppShell::Init(); failed: close(mPipeFDs[0]); close(mPipeFDs[1]); mPipeFDs[0] = mPipeFDs[1] = 0; return NS_ERROR_FAILURE; }
static void create_send_source(void) { GSource *send_source = g_io_create_watch(send_channel, G_IO_OUT | G_IO_FAILURE); g_io_channel_unref(send_channel); g_source_set_callback(send_source, (GSourceFunc) send_commands_cb, NULL, send_source_destroy_cb); send_source_id = g_source_attach(send_source, NULL); }
/** * Initializes the polling system. This must be called before * any other functions in this module. * * @returns TRUE if initialization succeeded, FALSE otherwise */ gboolean gam_dnotify_init(void) { struct sigaction act; int fds[2]; GSource *source; g_return_val_if_fail(gam_poll_dnotify_init (), FALSE); if (pipe(fds) < 0) { g_warning("Could not create pipe.\n"); return FALSE; } pipe_read_ioc = g_io_channel_unix_new(fds[0]); pipe_write_ioc = g_io_channel_unix_new(fds[1]); g_io_channel_set_flags(pipe_read_ioc, G_IO_FLAG_NONBLOCK, NULL); g_io_channel_set_flags(pipe_write_ioc, G_IO_FLAG_NONBLOCK, NULL); source = g_io_create_watch(pipe_read_ioc, G_IO_IN | G_IO_HUP | G_IO_ERR); g_source_set_callback(source, gam_dnotify_pipe_handler, NULL, NULL); g_source_attach(source, NULL); g_source_unref(source); /* setup some signal stuff */ act.sa_sigaction = dnotify_signal_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; sigaction(SIGRTMIN, &act, NULL); /* catch SIGIO as well (happens when the realtime queue fills up) */ act.sa_sigaction = overflow_signal_handler; sigemptyset(&act.sa_mask); sigaction(SIGIO, &act, NULL); changes = g_queue_new(); path_hash = g_hash_table_new(g_str_hash, g_str_equal); fd_hash = g_hash_table_new(g_direct_hash, g_direct_equal); GAM_DEBUG(DEBUG_INFO, "dnotify initialized\n"); gam_server_install_kernel_hooks (GAMIN_K_DNOTIFY, gam_dnotify_add_subscription, gam_dnotify_remove_subscription, gam_dnotify_remove_all_for, gam_dnotify_directory_handler, gam_dnotify_file_handler); return TRUE; }
/** * soup_add_io_watch: * @async_context: the #GMainContext to dispatch the I/O watch in, or * %NULL for the default context * @chan: the #GIOChannel to watch * @condition: the condition to watch for * @function: the callback to invoke when @condition occurs * @data: user data to pass to @function * * Adds an I/O watch as with g_io_add_watch(), but using the given * @async_context. * * Return value: a #GSource, which can be removed from @async_context * with g_source_destroy(). **/ GSource * soup_add_io_watch (GMainContext *async_context, GIOChannel *chan, GIOCondition condition, GIOFunc function, gpointer data) { GSource *watch = g_io_create_watch (chan, condition); g_source_set_callback (watch, (GSourceFunc) function, data, NULL); g_source_attach (watch, async_context); g_source_unref (watch); return watch; }
void add_source(GMainContext *context) { GIOChannel* channel; GSource* source; channel = g_io_channel_unix_new(1); source = g_io_create_watch(channel, G_IO_IN); g_io_channel_unref(channel); g_source_set_callback(source, (GSourceFunc)callback, channel, NULL); g_source_attach(source, context); g_source_unref(source); }
bool YapClient::connect() { // connect to remote server struct sockaddr_un socketAddr; d->cmdSocketFd = ::socket(PF_LOCAL, SOCK_STREAM, 0); if (d->cmdSocketFd < 0) return false; memset(&socketAddr, 0, sizeof(socketAddr)); socketAddr.sun_family = AF_LOCAL; strncpy(socketAddr.sun_path, d->cmdSocketPath, G_N_ELEMENTS(socketAddr.sun_path)); socketAddr.sun_path[G_N_ELEMENTS(socketAddr.sun_path)-1] = '\0'; if (::connect(d->cmdSocketFd, (struct sockaddr*) &socketAddr, SUN_LEN(&socketAddr)) != 0) { close(d->cmdSocketFd); d->cmdSocketFd = -1; fprintf(stderr, "YAP: Failed to connect to server\n"); return false; } // send our msg server socket path int16_t strLen = ::strlen(d->msgServerSocketPath); int16_t pktLen = bswap_16(strLen); if (!writeSocket(d->cmdSocketFd, (char*) &pktLen, 2)) return false; if (!writeSocket(d->cmdSocketFd, d->msgServerSocketPath, strLen)) return false; strLen = ::strlen(d->msgServerSocketPostfix); pktLen = bswap_16(strLen); if (!writeSocket(d->cmdSocketFd, (char*) &pktLen, 2)) return false; if (!writeSocket(d->cmdSocketFd, d->msgServerSocketPostfix, strLen)) return false; // Add io channel to know when the command socket is disconnected. d->cmdIoChannel = g_io_channel_unix_new(d->cmdSocketFd); d->cmdIoSource = g_io_create_watch(d->cmdIoChannel, (GIOCondition) (G_IO_HUP)); g_source_set_callback(d->cmdIoSource, (GSourceFunc) YapClientPriv::ioCallback, this, NULL); g_source_attach(d->cmdIoSource, d->mainCtxt); return true; }
GSource* gattlib_watch_connection_full(GIOChannel* io, GIOCondition condition, GIOFunc func, gpointer user_data, GDestroyNotify notify) { // Create a main loop source GSource *source = g_io_create_watch (io, condition); assert(source != NULL); g_source_set_callback (source, (GSourceFunc)func, user_data, notify); // Attaches it to the main loop context guint id = g_source_attach(source, g_gattlib_thread.loop_context); g_source_unref (source); assert(id != 0); return source; }
PIpcAsyncCallerBase::PIpcAsyncCallerBase(GMainLoop* loop) { int retval = ::pipe(m_pipeFd); if (retval) {} // setup an iochannel on the read end of the pipe m_ioChannel = g_io_channel_unix_new(m_pipeFd[0]); m_ioSource = g_io_create_watch(m_ioChannel, (GIOCondition) G_IO_IN); g_source_set_callback(m_ioSource, (GSourceFunc) callback, this, NULL); g_source_set_can_recurse(m_ioSource, true); GMainContext* ctxt = g_main_loop_get_context(loop); g_source_attach(m_ioSource, ctxt); pthread_mutex_init(&m_mutex, NULL); }
/** * Initialize this plugin dir watchData. * * @return true if successful, false if not. */ bool PluginDirWatcher::init(const char* path) { assert(path != NULL); if (mPath) { free(mPath); } mPath = strdup(path); g_debug("Adding plugin watchData for '%s'", mPath); struct SourceWatchData *watchData = g_new0(struct SourceWatchData, 1); watchData->notifyfd = -1; watchData->watchfd = -1; watchData->notifyfd = inotify_init(); if (watchData->notifyfd < 0) { g_warning("Error initializing inotify"); return false; } watchData->watchfd = inotify_add_watch(watchData->notifyfd, mPath, IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVED_FROM | IN_MOVED_TO | IN_CLOSE_WRITE | IN_ONLYDIR | 0); if (watchData->watchfd < 0) { perror("Can't call inotify_add_watchData"); return false; } GIOChannel* chan = g_io_channel_unix_new(watchData->notifyfd); mSource = g_io_create_watch(chan, G_IO_IN); g_source_set_callback(mSource, reinterpret_cast<GSourceFunc>(watch_func), watchData, watch_destroy); GMainLoop* pLoop = BrowserServer::instance()->mainLoop(); g_source_attach (mSource, g_main_loop_get_context(pLoop)); g_io_channel_unref(chan); return true; }
static void create_child (void) { int pid; GIOChannel *in_channels[2]; GIOChannel *out_channels[2]; GSource *source; io_pipe (in_channels); io_pipe (out_channels); pid = fork (); if (pid > 0) /* Parent */ { g_io_channel_close (in_channels[0]); g_io_channel_close (out_channels[1]); source = g_io_create_watch (out_channels[0], G_IO_IN | G_IO_HUP); g_source_set_closure (source, g_cclosure_new (G_CALLBACK (input_callback), in_channels[1], (GClosureNotify)g_io_channel_unref)); g_source_attach (source, NULL); g_source_unref (source); g_io_channel_unref (in_channels[0]); g_io_channel_unref (out_channels[0]); g_io_channel_unref (out_channels[1]); } else if (pid == 0) /* Child */ { g_io_channel_close (in_channels[1]); g_io_channel_close (out_channels[0]); setsid (); run_child (in_channels[0], out_channels[1]); } else /* Error */ { fprintf (stderr, "Cannot fork: %s\n", g_strerror (errno)); exit (1); } }
static GSource * create_watch_fd (int fd, GIOCondition cond, GIOFunc func, gpointer data) { GIOChannel *channel; GSource *source; channel = create_io_channel (fd); source = g_io_create_watch (channel, cond); g_source_set_callback (source, (GSourceFunc)func, data, NULL); g_io_channel_unref (channel); return source; }
static int g_io_add_watch_tothread(GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data) { GSource *source; guint id; g_return_val_if_fail(channel != NULL, 0); source = g_io_create_watch(channel, condition); g_source_set_callback(source, (GSourceFunc) func, user_data, NULL); id = g_source_attach(source, g_main_context_get_thread_default()); g_source_unref(source); return id; }
static guint add_io_watch(GMainContext *main_context, GIOChannel *channel, GIOCondition condition, GIOFunc func, gpointer user_data) { GSource *source; guint id; source = g_io_create_watch(channel, condition); g_source_set_callback(source, (GSourceFunc)func, user_data, NULL); id = g_source_attach(source, main_context); g_source_unref(source); return id; }
static void shm_reader_add_fd_source (ShmReader *self, int fd, GIOFunc callback, gpointer user_data, GDestroyNotify notify) { GIOChannel *channel; GSource *source; channel = g_io_channel_unix_new (fd); source = g_io_create_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); g_io_channel_unref (channel); g_source_set_callback (source, (GSourceFunc)callback, user_data, notify); g_source_attach (source, self->priv->context); self->priv->source = source; }
gpointer thread2_entry(gpointer data) { GIOChannel *channel; GSource *source; g_print("thread2_entry() %d\n", (pid_t) syscall (SYS_gettid)); main_loop2 = g_main_loop_new(thread2_context, FALSE); channel = g_io_channel_unix_new(0); source = g_io_create_watch(channel, G_IO_IN); g_source_set_callback(source, (GSourceFunc) input_callback, NULL, NULL); g_source_attach(source, thread2_context); g_source_unref(source); g_main_loop_run(main_loop2); }
static void nmt_newt_form_real_show (NmtNewtForm *form) { if (!keypress_source) { GIOChannel *io; io = g_io_channel_unix_new (STDIN_FILENO); keypress_source = g_io_create_watch (io, G_IO_IN); g_source_set_can_recurse (keypress_source, TRUE); g_source_set_callback (keypress_source, (GSourceFunc) nmt_newt_form_keypress_callback, NULL, NULL); g_source_attach (keypress_source, NULL); g_io_channel_unref (io); } nmt_newt_form_build (form); form_stack = g_slist_prepend (form_stack, g_object_ref (form)); nmt_newt_form_redraw (form); }
static gpointer xmms_ipc_client_thread (gpointer data) { xmms_ipc_client_t *client = data; GSource *source; source = g_io_create_watch (client->iochan, G_IO_IN | G_IO_ERR | G_IO_HUP); g_source_set_callback (source, (GSourceFunc) xmms_ipc_client_read_cb, (gpointer) client, NULL); g_source_attach (source, g_main_loop_get_context (client->ml)); g_source_unref (source); g_main_loop_run (client->ml); xmms_ipc_client_destroy (client); return NULL; }
static guint watch_io (GCutEventLoop *loop, GIOChannel *channel, GIOCondition condition, GIOFunc function, gpointer data) { GCutGLibEventLoopPrivate *priv; guint watch_tag; GSource *watch_source; priv = GCUT_GLIB_EVENT_LOOP_GET_PRIVATE(loop); watch_source = g_io_create_watch(channel, condition); g_source_set_callback(watch_source, (GSourceFunc)function, data, NULL); watch_tag = g_source_attach(watch_source, g_main_loop_get_context(priv->loop)); g_source_unref(watch_source); return watch_tag; }
int inotify_monitor_start(struct inotify_monitor *im) { GIOChannel *inotify_channel; GSource *source; im->inotify_fd = inotify_init(); if (im->inotify_fd == -1) { a6o_log(ARMADITO_LOG_MODULE, ARMADITO_LOG_LEVEL_ERROR, MODULE_LOG_NAME ": " "inotify_init failed (%s)", strerror(errno)); return -1; } inotify_channel = g_io_channel_unix_new(im->inotify_fd); /* g_io_add_watch(inotify_channel, G_IO_IN, inotify_cb, im); */ source = g_io_create_watch(inotify_channel, G_IO_IN); g_source_set_callback(source, (GSourceFunc)inotify_cb, im, NULL); g_source_attach(source, access_monitor_get_main_context(im->monitor)); g_source_unref(source); return 0; }
static gpointer tcp_connect_init(gpointer data) { struct tcp_connect *c = data; /* create a connect source */ GIOChannel *channel = g_io_channel_new_socket(c->fd); c->source = g_io_create_watch(channel, G_IO_OUT); g_io_channel_unref(channel); g_source_set_callback(c->source, (GSourceFunc)tcp_connect_event, c, NULL); g_source_attach(c->source, io_thread_context()); /* create a timeout source */ if (c->timeout_ms > 0) c->timeout_source = io_thread_timeout_add(c->timeout_ms, tcp_connect_timeout, c); return NULL; }
static void shm_writer_add_fd_source (ShmWriter *self, int fd, GIOFunc callback, gpointer user_data, GDestroyNotify notify) { GIOChannel *channel; GSource *source; channel = g_io_channel_unix_new (fd); source = g_io_create_watch (channel, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL); g_io_channel_unref (channel); /* Weak ref so the source will be destroyed when the writer is destroyed */ g_object_weak_ref (G_OBJECT (self), shm_writer_destroy_source, source); g_source_set_callback (source, (GSourceFunc)callback, user_data, notify); g_source_attach (source, self->priv->context); g_source_unref (source); }