Skip to content

GLib.Source

record (struct)

The GSource struct is an opaque data type representing an event source.

Constructors

new

@classmethod
def new(cls, source_funcs: SourceFuncs, struct_size: int) -> Source

Creates a new Source structure.

The size is specified to allow creating structures derived from Source that contain additional data. The size passed in must be at least sizeof (GSource).

The source will not initially be associated with any MainContext and must be added to one with Source.attach before it will be executed.

Parameters:

  • source_funcs — structure containing functions that implement the source‘s behavior
  • struct_size — size of the Source structure to create, in bytes

Methods

add_child_source

def add_child_source(self, child_source: Source) -> None

Adds child_source to source as a ‘polled’ source.

When source is added to a MainContext, child_source will be automatically added with the same priority. When child_source is triggered, it will cause source to dispatch (in addition to calling its own callback), and when source is destroyed, it will destroy child_source as well.

The source will also still be dispatched if its own prepare/check functions indicate that it is ready.

If you don’t need child_source to do anything on its own when it triggers, you can call g_source_set_dummy_callback() on it to set a callback that does nothing (except return true if appropriate).

The source will hold a reference on child_source while child_source is attached to it.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

Parameters:

  • child_source — a second source that source should ‘poll’

add_poll

def add_poll(self, fd: PollFD) -> None

Adds a file descriptor to the set of file descriptors polled for this source.

This is usually combined with Source.new to add an event source. The event source’s check function will typically test the revents field in the PollFD struct and return true if events need to be processed.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

Using this API forces the linear scanning of event sources on each main loop iteration. Newly-written event sources should try to use g_source_add_unix_fd() instead of this API.

Parameters:

  • fd — a PollFD structure holding information about a file descriptor to watch

add_unix_fd

def add_unix_fd(self, fd: int, events: IOCondition | int) -> int

Monitors fd for the IO events in events.

The tag returned by this function can be used to remove or modify the monitoring of the fd using Source.remove_unix_fd or Source.modify_unix_fd.

It is not necessary to remove the file descriptor before destroying the source; it will be cleaned up automatically.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

As the name suggests, this function is not available on Windows.

Parameters:

  • fd — the file descriptor to monitor
  • events — an event mask

attach

def attach(self, context: MainContext | None = ...) -> int

Adds a Source to a context so that it will be executed within that context.

Remove it by calling Source.destroy.

This function is safe to call from any thread, regardless of which thread the context is running in.

Parameters:

  • context — a main context (if NULL, the global-default main context will be used)

destroy

def destroy(self) -> None

Removes a source from its MainContext, if any, and marks it as destroyed.

The source cannot be subsequently added to another context. It is safe to call this on sources which have already been removed from their context.

This does not unref the Source: if you still hold a reference, use Source.unref to drop it.

This function is safe to call from any thread, regardless of which thread the MainContext is running in.

If the source is currently attached to a MainContext, destroying it will effectively unset the callback similar to calling Source.set_callback. This can mean, that the data’s DestroyNotify gets called right away.

dup_context

def dup_context(self) -> MainContext | None

Gets a reference to the MainContext with which the source is associated.

You can call this on a source that has been destroyed. You can always call this function on the source returned from main_current_source.

get_can_recurse

def get_can_recurse(self) -> bool

Checks whether a source is allowed to be called recursively.

See Source.set_can_recurse.

get_context

def get_context(self) -> MainContext | None

Gets the MainContext with which the source is associated.

You can call this on a source that has been destroyed, provided that the MainContext it was attached to still exists (in which case it will return that MainContext). In particular, you can always call this function on the source returned from main_current_source. But calling this function on a source whose MainContext has been destroyed is an error.

If the associated MainContext could be destroy concurrently from a different thread, then this function is not safe to call and Source.dup_context should be used instead.

get_current_time

def get_current_time(self, timeval: TimeVal) -> None

:::warning Deprecated since 2.28 This API is deprecated. :::

This function ignores source and is otherwise the same as get_current_time.

Parameters:

  • timevalTimeVal structure in which to store current time

get_id

def get_id(self) -> int

Returns the numeric ID for a particular source.

The ID of a source is a positive integer which is unique within a particular main loop context. The reverse mapping from ID to source is done by MainContext.find_source_by_id.

You can only call this function while the source is associated to a MainContext instance; calling this function before Source.attach or after Source.destroy yields undefined behavior. The ID returned is unique within the MainContext instance passed to Source.attach.

get_name

def get_name(self) -> str | None

Gets a name for the source, used in debugging and profiling.

The name may be NULL if it has never been set with Source.set_name.

get_priority

def get_priority(self) -> int

Gets the priority of a source.

get_ready_time

def get_ready_time(self) -> int

Gets the ‘ready time’ of source, as set by Source.set_ready_time.

Any time before or equal to the current monotonic time (including zero) is an indication that the source will fire immediately.

get_time

def get_time(self) -> int

Gets the time to be used when checking this source.

The advantage of calling this function over calling get_monotonic_time directly is that when checking multiple sources, GLib can cache a single value instead of having to repeatedly get the system monotonic time.

The time here is the system monotonic time, if available, or some other reasonable alternative otherwise. See get_monotonic_time.

is_destroyed

def is_destroyed(self) -> bool

Returns whether source has been destroyed.

This is important when you operate upon your objects from within idle handlers, but may have freed the object before the dispatch of your idle handler.

static gboolean
idle_callback (gpointer data)
{
  SomeWidget *self = data;

  g_mutex_lock (&self->idle_id_mutex);
  // do stuff with self
  self->idle_id = 0;
  g_mutex_unlock (&self->idle_id_mutex);

  return G_SOURCE_REMOVE;
}

static void
some_widget_do_stuff_later (SomeWidget *self)
{
  g_mutex_lock (&self->idle_id_mutex);
  self->idle_id = g_idle_add (idle_callback, self);
  g_mutex_unlock (&self->idle_id_mutex);
}

static void
some_widget_init (SomeWidget *self)
{
  g_mutex_init (&self->idle_id_mutex);

  // ...
}

static void
some_widget_finalize (GObject *object)
{
  SomeWidget *self = SOME_WIDGET (object);

  if (self->idle_id)
    g_source_remove (self->idle_id);

  g_mutex_clear (&self->idle_id_mutex);

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

This will fail in a multi-threaded application if the widget is destroyed before the idle handler fires due to the use after free in the callback. A solution, to this particular problem, is to check to if the source has already been destroy within the callback.

static gboolean
idle_callback (gpointer data)
{
  SomeWidget *self = data;

  g_mutex_lock (&self->idle_id_mutex);
  if (!g_source_is_destroyed (g_main_current_source ()))
    {
      // do stuff with self
    }
  g_mutex_unlock (&self->idle_id_mutex);

  return FALSE;
}

Calls to this function from a thread other than the one acquired by the MainContext the Source is attached to are typically redundant, as the source could be destroyed immediately after this function returns. However, once a source is destroyed it cannot be un-destroyed, so this function can be used for opportunistic checks from any thread.

modify_unix_fd

def modify_unix_fd(self, tag: int, new_events: IOCondition | int) -> None

Updates the event mask to watch for the file descriptor identified by tag.

The tag is the tag returned from Source.add_unix_fd.

If you want to remove a file descriptor, don’t set its event mask to zero. Instead, call Source.remove_unix_fd.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

As the name suggests, this function is not available on Windows.

Parameters:

query_unix_fd

def query_unix_fd(self, tag: int) -> IOCondition

Queries the events reported for the file descriptor corresponding to tag on source during the last poll.

The return value of this function is only defined when the function is called from the check or dispatch functions for source.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

As the name suggests, this function is not available on Windows.

Parameters:

ref

def ref(self) -> Source

Increases the reference count on a source by one.

remove_child_source

def remove_child_source(self, child_source: Source) -> None

Detaches child_source from source and destroys it.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

Parameters:

remove_poll

def remove_poll(self, fd: PollFD) -> None

Removes a file descriptor from the set of file descriptors polled for this source.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

Parameters:

remove_unix_fd

def remove_unix_fd(self, tag: int) -> None

Reverses the effect of a previous call to Source.add_unix_fd.

You only need to call this if you want to remove a file descriptor from being watched while keeping the same source around. In the normal case you will just want to destroy the source.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

As the name suggests, this function is not available on Windows.

Parameters:

set_callback

def set_callback(self, func: SourceFunc) -> None

Sets the callback function for a source. The callback for a source is called from the source’s dispatch function.

The exact type of func depends on the type of source; ie. you should not count on func being called with data as its first parameter. Cast func with GLib.SOURCE_FUNC to avoid warnings about incompatible function types.

See main loop memory management for details on how to handle memory management of data.

Typically, you won’t use this function. Instead use functions specific to the type of source you are using, such as idle_add or timeout_add.

It is safe to call this function multiple times on a source which has already been attached to a context. The changes will take effect for the next time the source is dispatched after this call returns.

Note that Source.destroy for a currently attached source has the effect of also unsetting the callback.

Parameters:

  • func — a callback function

set_callback_indirect

def set_callback_indirect(self, callback_data: int | None, callback_funcs: SourceCallbackFuncs) -> None

Sets the callback function storing the data as a reference counted callback ‘object’.

This is used internally. Note that calling Source.set_callback_indirect assumes an initial reference count on callback_data, and thus callback_funcs->unref will eventually be called once more than callback_funcs->ref.

It is safe to call this function multiple times on a source which has already been attached to a context. The changes will take effect for the next time the source is dispatched after this call returns.

Parameters:

  • callback_data — pointer to callback data ‘object’
  • callback_funcs — functions for reference counting callback_data and getting the callback and data

set_can_recurse

def set_can_recurse(self, can_recurse: bool) -> None

Sets whether a source can be called recursively.

If can_recurse is true, then while the source is being dispatched then this source will be processed normally. Otherwise, all processing of this source is blocked until the dispatch function returns.

Parameters:

  • can_recurse — whether recursion is allowed for this source

set_funcs

def set_funcs(self, funcs: SourceFuncs) -> None

Sets the source functions of an unattached source.

These can be used to override the default implementations for the type of source.

Parameters:

  • funcs — the new source functions

set_name

def set_name(self, name: str) -> None

Sets a name for the source, used in debugging and profiling.

The name defaults to NULL.

The source name should describe in a human-readable way what the source does. For example, ‘X11 event queue’ or ‘GTK repaint idle handler’.

It is permitted to call this function multiple times, but is not recommended due to the potential performance impact. For example, one could change the name in the check function of a SourceFuncs to include details like the event type in the source name.

Use caution if changing the name while another thread may be accessing it with Source.get_name; that function does not copy the value, and changing the value will free it while the other thread may be attempting to use it.

Also see Source.set_static_name.

Parameters:

  • name — debug name for the source

set_priority

def set_priority(self, priority: int) -> None

Sets the priority of a source.

While the main loop is being run, a source will be dispatched if it is ready to be dispatched and no sources at a higher (numerically smaller) priority are ready to be dispatched.

A child source always has the same priority as its parent. It is not permitted to change the priority of a source once it has been added as a child of another source.

Parameters:

  • priority — the new priority

set_ready_time

def set_ready_time(self, ready_time: int) -> None

Sets a source to be dispatched when the given monotonic time is reached (or passed).

If the monotonic time is in the past (as it always will be if ready_time is 0) then the source will be dispatched immediately.

If ready_time is -1 then the source is never woken up on the basis of the passage of time.

Dispatching the source does not reset the ready time. You should do so yourself, from the source dispatch function.

Note that if you have a pair of sources where the ready time of one suggests that it will be delivered first but the priority for the other suggests that it would be delivered first, and the ready time for both sources is reached during the same main context iteration, then the order of dispatch is undefined.

It is a no-op to call this function on a Source which has already been destroyed with Source.destroy.

This API is only intended to be used by implementations of Source. Do not call this API on a Source that you did not create.

Parameters:

  • ready_time — the monotonic time at which the source will be ready; 0 for ‘immediately’, -1 for ‘never’

set_static_name

def set_static_name(self, name: str) -> None

A variant of Source.set_name that does not duplicate the name, and can only be used with string literals.

Parameters:

  • name — debug name for the source

unref

def unref(self) -> None

Decreases the reference count of a source by one.

If the resulting reference count is zero the source and associated memory will be destroyed.

Static functions

remove

@staticmethod
def remove(tag: int) -> bool

Removes the source with the given ID from the default main context.

You must use Source.destroy for sources added to a non-default main context.

The ID of a Source is given by Source.get_id, or will be returned by the functions Source.attach, idle_add, GLib.idle_add_full, timeout_add, GLib.timeout_add_full, child_watch_add, GLib.child_watch_add_full, io_add_watch, and GLib.io_add_watch_full.

It is a programmer error to attempt to remove a non-existent source.

More specifically: source IDs can be reissued after a source has been destroyed and therefore it is never valid to use this function with a source ID which may have already been removed. An example is when scheduling an idle to run in another thread with idle_add: the idle may already have run and been removed by the time this function is called on its (now invalid) source ID. This source ID may have been reissued, leading to the operation being performed against the wrong source.

Parameters:

  • tag — the ID of the source to remove.

remove_by_funcs_user_data

@staticmethod
def remove_by_funcs_user_data(funcs: SourceFuncs, user_data: int | None = ...) -> bool

Removes a source from the default main loop context given the source functions and user data.

If multiple sources exist with the same source functions and user data, only one will be destroyed.

Parameters:

  • funcs — the source_funcs passed to Source.new
  • user_data — the user data for the callback

remove_by_user_data

@staticmethod
def remove_by_user_data(user_data: int | None = ...) -> bool

Removes a source from the default main loop context given the user data for the callback.

If multiple sources exist with the same user data, only one will be destroyed.

Parameters:

  • user_data — the user_data for the callback

set_name_by_id

@staticmethod
def set_name_by_id(tag: int, name: str) -> None

Sets the name of a source using its ID.

This is a convenience utility to set source names from the return value of idle_add, timeout_add, etc.

It is a programmer error to attempt to set the name of a non-existent source.

More specifically: source IDs can be reissued after a source has been destroyed and therefore it is never valid to use this function with a source ID which may have already been removed. An example is when scheduling an idle to run in another thread with idle_add: the idle may already have run and been removed by the time this function is called on its (now invalid) source ID. This source ID may have been reissued, leading to the operation being performed against the wrong source.

Parameters:

  • tag — a source ID
  • name — debug name for the source

Properties

callback_data

callback_data: int  # read/write

callback_funcs

callback_funcs: SourceCallbackFuncs  # read/write

source_funcs

source_funcs: SourceFuncs  # read/write

ref_count

ref_count: int  # read/write

context

context: MainContext  # read/write

priority

priority: int  # read/write

flags

flags: int  # read/write

source_id

source_id: int  # read/write

poll_fds

poll_fds: list[int]  # read/write

prev

prev: Source  # read/write

next

next: Source  # read/write

name

name: str  # read/write

priv

priv: SourcePrivate  # read/write