Glib bits'n'pieces
- From: Roger Leigh <rleigh whinlatter ukfsn org>
- To: gtk-devel-list gnome org
- Subject: Glib bits'n'pieces
- Date: Sun, 24 Apr 2005 11:15:56 +0100
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hi folks,
After a post a few weeks ago about writing a GSource for UNIX signals,
I spent a few nights writing one, which is now mostly done (I've
attached the header; any comments would be appreciated). The main
issue I have is how to avoid overrunning the signal buffer if flooded
with signals before the mainloop runs (I can't realloc memory in a
signal handler, so I rely on a fixed-length g_renew'd buffer which is
resized in the mainloop if needed, but by that time I've lost data).
I also realised that what I really wanted was for the GSource to be a
GObject, so that I could connect multiple event handlers rather than a
single callback. The reason for this is that due to signals being
coarse-grained (per-process), the handler object has to be a
singleton, and so I wanted the handlers to work like GdkEvents, where
if I can't (or don't want to) handle a particular event, I return
FALSE and let the next handler process it. However, this is not
currently possible, restricting me to a single handler function per
process, which is not extensible.
Looking at GSource itself, it looks like it would be cleaner and
easier to use if it was a GObject, and the same applies to quite a
number of glib types, including the container types. If the list
types, for example, were GObjects, some operations would become rather
more efficient if the object was a list head, which would then allow
for caching, and not returning the first GList node for every
operation changing the list saves needlessly traversing the list when
e.g. appending. It might also be possible to restrict the list
contents to a particular GType, set callbacks for automatic sorting,
freeing nodes etc., and store GValues rather than gpointers in the
nodes. This would also provide the opportunity to add common
container interfaces e.g. GIterator, GContainer for all container
types (which could also be implemented by e.g. GtkContainer).
Are any changes like this planned for glib 3.x?
Thanks,
Roger
#include <sys/types.h>
#include <signal.h>
#include <time.h>
#include <glib/gtypes.h>
#include <glib/gmain.h>
typedef struct _GUnixSignalAny GUnixSignalAny;
typedef struct _GUnixSignalIllegal GUnixSignalIllegal;
typedef struct _GUnixSignalFpe GUnixSignalFpe;
typedef struct _GUnixSignalSegv GUnixSignalSegv;
typedef struct _GUnixSignalBus GUnixSignalBus;
typedef struct _GUnixSignalTrap GUnixSignalTrap;
typedef struct _GUnixSignalChild GUnixSignalChild;
typedef struct _GUnixSignalPoll GUnixSignalPoll;
typedef union _GUnixSignal GUnixSignal;
typedef void (*GUnixSignalFunc)(GUnixSignal *signal,
gpointer user_data);
typedef enum
{
#ifdef SIGHUP
G_UNIX_SIGNAL_HANGUP = SIGHUP,
#endif
#ifdef SIGINT
G_UNIX_SIGNAL_INTERRUPT = SIGINT,
#endif
#ifdef SIGQUIT
G_UNIX_SIGNAL_QUIT = SIGQUIT,
#endif
#ifdef SIGILL
G_UNIX_SIGNAL_ILLEGAL = SIGILL,
#endif
#ifdef SIGABRT
G_UNIX_SIGNAL_ABORT = SIGABRT,
#endif
#ifdef SIGFPE
G_UNIX_SIGNAL_FPE = SIGFPE,
#endif
#ifdef SIGKILL
G_UNIX_SIGNAL_KILL = SIGKILL,
#endif
#ifdef SIGSEGV
G_UNIX_SIGNAL_SEGV = SIGSEGV,
#endif
#ifdef SIGPIPE
G_UNIX_SIGNAL_PIPE = SIGPIPE,
#endif
#ifdef SIGALRM
G_UNIX_SIGNAL_ALARM = SIGALRM,
#endif
#ifdef SIGTERM
G_UNIX_SIGNAL_TERMINATE = SIGTERM,
#endif
#ifdef SIGUSR1
G_UNIX_SIGNAL_USER1 = SIGUSR1,
#endif
#ifdef SIGUSR2
G_UNIX_SIGNAL_USER2 = SIGUSR2,
#endif
#ifdef SIGCHLD
G_UNIX_SIGNAL_CHILD = SIGCHLD,
#endif
#ifdef SIGCONT
G_UNIX_SIGNAL_CONTINUE = SIGCONT,
#endif
#ifdef SIGSTOP
G_UNIX_SIGNAL_STOP = SIGSTOP,
#endif
#ifdef SIGTSTP
G_UNIX_SIGNAL_TTYSTOP = SIGTSTP,
#endif
#ifdef SIGTTIN
G_UNIX_SIGNAL_TTYINPUT = SIGTTIN,
#endif
#ifdef SIGTTOU
G_UNIX_SIGNAL_TTYOUTPUT = SIGTTOU
#endif
} GUnixSignalType;
typedef enum
{
#ifdef SI_ASYNCNL
G_UNIX_SIGNAL_TYPE_ASYNC_NAME_LOOKUP = SI_ASYNCNL,
#endif
#ifdef SI_TKILL
G_UNIX_SIGNAL_TYPE_TKILL = SI_TKILL,
#endif
#ifdef SI_SIGIO
G_UNIX_SIGNAL_TYPE_SIGIO = SI_SIGIO,
#endif
#ifdef SI_ASYNCIO
G_UNIX_SIGNAL_TYPE_ASYNC_IO = SI_ASYNCIO,
#endif
#ifdef SI_MESGQ
G_UNIX_SIGNAL_TYPE_MESSAGEG_QUEUE = SI_MESGQ,
#endif
#ifdef SI_TIMER
G_UNIX_SIGNAL_TYPE_TIMER = SI_TIMER,
#endif
#ifdef SI_QUEUE
G_UNIX_SIGNAL_TYPE_QUEUE = SI_QUEUE,
#endif
#ifdef SI_USER
G_UNIX_SIGNAL_TYPE_USER = SI_USER,
#endif
#ifdef SI_KERNEL
G_UNIX_SIGNAL_TYPE_KERNEL = SI_KERNEL,
#endif
G_UNIX_SIGNAL_TYPE_SPECIFIC
} GUnixSignalCode;
typedef enum
{
#ifdef ILL_ILLOPC
G_UNIX_SIGNAL_ILLEGAL_OPCODE = ILL_ILLOPC,
#endif
#ifdef ILL_ILLOPN
G_UNIX_SIGNAL_ILLEGAL_OPERAND = ILL_ILLOPN,
#endif
#ifdef ILL_ILLADR
G_UNIX_SIGNAL_ILLEGAL_ADDRESS = ILL_ILLADR,
#endif
#ifdef ILL_ILLTRP
G_UNIX_SIGNAL_ILLEGAL_TRAP = ILL_ILLTRP,
#endif
#ifdef ILL_PRVOPC
G_UNIX_SIGNAL_ILLEGAL_PRIV_OPCODE = ILL_PRVOPC,
#endif
#ifdef ILL_PRVREG
G_UNIX_SIGNAL_ILLEGAL_PRIV_REGISTER = ILL_PRVREG,
#endif
#ifdef ILL_COPROC
G_UNIX_SIGNAL_ILLEGAL_COPROCESSOR = ILL_COPROC,
#endif
#ifdef ILL_BADSTK
G_UNIX_SIGNAL_ILLEGAL_STACK = ILL_BADSTK
#endif
} GUnixSignalIllegalCode;
typedef enum
{
#ifdef FPE_INTDIV
G_UNIX_SIGNAL_INTEGER_ZERO_DIVIDE = FPE_INTDIV,
#endif
#ifdef FPE_INTOVF
G_UNIX_SIGNAL_INTEGER_OVERFLOW = FPE_INTOVF,
#endif
#ifdef FPE_FLTDIV
G_UNIX_SIGNAL_FLOAT_ZERO_DIVIDE = FPE_FLTDIV,
#endif
#ifdef FPE_FLTOVF
G_UNIX_SIGNAL_FLOAT_OVERFLOW = FPE_FLTOVF,
#endif
#ifdef FPE_FLTUND
G_UNIX_SIGNAL_FLOAT_UNDERFLOW = FPE_FLTUND,
#endif
#ifdef FPE_FLTRES
G_UNIX_SIGNAL_FLOAT_INEXACT = FPE_FLTRES,
#endif
#ifdef FPE_FLTINV
G_UNIX_SIGNAL_FLOAT_INVALID = FPE_FLTINV,
#endif
#ifdef FPE_FLTSUB
G_UNIX_SIGNAL_FLOAT_SUBSCRIPT_RANGE = FPE_FLTSUB
#endif
} GUnixSignalFpeCode;
typedef enum
{
#ifdef SEGV_MAPERR
G_UNIX_SIGNAL_SEGV_MAP_ERROR = SEGV_MAPERR,
#endif
#ifdef SEGV_ACCERR
G_UNIX_SIGNAL_SEGV_ACCESS_ERROR = SEGV_ACCERR
#endif
} GUnixSignalSegvCode;
typedef enum
{
#ifdef BUS_ADRALN
G_UNIX_SIGNAL_BUS_ADDRESS_ALIGNMENT = BUS_ADRALN,
#endif
#ifdef BUS_ADRERR
G_UNIX_SIGNAL_BUS_ADDRESS_ERROR = BUS_ADRERR,
#endif
#ifdef BUS_OBJERR
G_UNIX_SIGNAL_BUS_OBJECT_ERROR = BUS_OBJERR
#endif
} GUnixSignalBusCode;
typedef enum
{
#ifdef TRAP_BRKPT
G_UNIX_SIGNAL_TRAP_BREAKPOINT = TRAP_BRKPT,
#endif
#ifdef TRAP_TRACE
G_UNIX_SIGNAL_TRAP_TRACE = TRAP_TRACE
#endif
} GUnixSignalTrapCode;
typedef enum
{
#ifdef CLD_EXITED
G_UNIX_SIGNAL_CHILD_EXITED = CLD_EXITED,
#endif
#ifdef CLD_KILLED
G_UNIX_SIGNAL_CHILD_KILLED = CLD_KILLED,
#endif
#ifdef CLD_DUMPED
G_UNIX_SIGNAL_CHILD_DUMPED = CLD_DUMPED,
#endif
#ifdef CLD_TRAPPED
G_UNIX_SIGNAL_CHILD_TRAPPED = CLD_TRAPPED,
#endif
#ifdef CLD_STOPPED
G_UNIX_SIGNAL_CHILD_STOPPED = CLD_STOPPED,
#endif
#ifdef CLD_CONTINUED
G_UNIX_SIGNAL_CHILD_CONTINUED = CLD_CONTINUED
#endif
} GUnixSignalChildCode;
typedef enum
{
#ifdef POLL_IN
G_UNIX_SIGNAL_POLL_INPUT = POLL_IN,
#endif
#ifdef POLL_OUT
G_UNIX_SIGNAL_POLL_OUTPUT = POLL_OUT,
#endif
#ifdef POLL_MSG
G_UNIX_SIGNAL_POLL_MESSAGE = POLL_MSG,
#endif
#ifdef POLL_ERR
G_UNIX_SIGNAL_POLL_ERROR = POLL_ERR,
#endif
#ifdef POLL_PRI
G_UNIX_SIGNAL_POLL_PRIORITY = POLL_PRI,
#endif
#ifdef POLL_HUP
G_UNIX_SIGNAL_POLL_HANGUP = POLL_HUP
#endif
} GUnixSignalPollCode;
struct _GUnixSignalAny
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
};
struct _GUnixSignalIllegal
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalIllegalCode scode;
void *addr;
};
struct _GUnixSignalFpe
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalFpeCode scode;
void *addr;
};
struct _GUnixSignalSegv
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalSegvCode scode;
void *addr;
};
struct _GUnixSignalBus
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalBusCode scode;
void *addr;
};
struct _GUnixSignalTrap
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalTrapCode scode;
};
struct _GUnixSignalChild
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalChildCode scode;
pid_t pid;
uid_t uid;
int status;
clock_t utime;
clock_t stime;
};
struct _GUnixSignalPoll
{
GUnixSignalType type;
int errno;
GUnixSignalCode code;
GUnixSignalPollCode scode;
int band;
int fd;
};
union _GUnixSignal
{
GUnixSignalType type;
GUnixSignalAny any;
GUnixSignalIllegal illegal;
GUnixSignalFpe fpe;
GUnixSignalSegv segv;
GUnixSignalBus bus;
GUnixSignalTrap trap;
GUnixSignalChild child;
GUnixSignalPoll poll;
};
GSource *
g_unix_signal_create_watch (void);
- --
Roger Leigh
Printing on GNU/Linux? http://gimp-print.sourceforge.net/
Debian GNU/Linux http://www.debian.org/
GPG Public Key: 0x25BFB848. Please sign and encrypt your mail.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
Comment: Processed by Mailcrypt 3.5.8 <http://mailcrypt.sourceforge.net/>
iD8DBQFCa3HZVcFcaSW/uEgRAlI7AJ9j7LL2xxj+PRFXKQv4krcI1+1RTQCg1AvI
CB2yxA435KZ33xJlOg3WVN8=
=YJIJ
-----END PGP SIGNATURE-----
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]