Next Previous Contents

5. Managing timers and other channels

In your applications, you may need to manage other input/output channels than an Ivy bus: a serial driver, the channels defined by a graphical toolkit, or simply stdin and stdout. The same applies for timers. You can either manage those channels or timers from the Ivy main loop, or instead use the main loop provided by another library.

5.1 Adding channels and timers to the Ivy main loop

Channels

You can get a channel to be managed from the Ivy main loop by using functions IvyChannelSetUp and IvyChannelClose.

Channel IvyChannelSetUp (HANDLE fd,
                        void* data,
                        ChannelHandleDelete handle_delete,
                        ChannelHandleRead handle_read);
ensures that function handle_read is called whenever data is read on file descriptor fd, and function handle_delete whenever fd is closed, and

void IvyChannelClose (Channel ch);
terminates the management of channel ch.

In what precedes, Channel is an opaque type defined by the Ivy C library, data is a pointer that will be passed to functions handle_read and handle_delete. It can be defined at will by users. The types HANDLE, ChannelHandleDelete and ChannelHandleRead are as follows:

Unix:
typedef int HANDLE;
Windows:
typedef SOCKET HANDLE;
typedef void (*ChannelHandleDelete)(void *data);
typedef void (*ChannelHandleRead)(Channel ch, HANDLE fd, void* data);

Timers

You can get a function to be repeatedly called by using function TimerRepeatAfter:

TimerId TimerRepeatAfter (int nbticks, long delay, TimerCb handle_timer, void* data);
ensures that function handle_timer is called nbticks times at intervals of delay seconds, thus creating a timer.

void TimerModify (TimerId id, long delay);
changes the delay used for timer id.

void TimerRemove (TimerId id);
deletes timer id, thus stopping it.

In what precedes, data is passed to handle_timer every time it is called. delay is expressed in milliseconds. If nbticks is set to TIMER_LOOP, then handle_timer will be called forever. TimerCb is as follows:

typedef void (*TimerCb)(TimerId id, void *data, unsigned long delta);

5.2 Adding Ivy to another main loop

Functions to be provided

You can decide to use the main loop from another toolkit such as the X Toolkit or the Tk toolkit. If you do that, you'll have to define three functions that Ivy will use to get its own channels managed by the other toolkit. The three following global variables should be defined:

ChannelInit channel_init;
ChannelSetUp channel_setup;
ChannelClose channel_close;

They should point to functions that respectively:

The types ChannelInit, ChannelSetUp and ChannelClose are defined as follows:

typedef void (*ChannelInit)(void);
typedef Channel (*ChannelSetUp)(
        HANDLE fd,
        void *data,
        ChannelHandleDelete handle_delete,
        ChannelHandleRead handle_read);
typedef void (*ChannelClose)( Channel channel );

Type to be defined

In order to implement the three previous functions, you will need to define the hidden type struct _channel (the type Channel is defined as struct _channel*). Use it to store the data provided by the other toolkit.

Overriding the Ivy main loop

In order to override the default definition of the three previous variables, you will need:


Next Previous Contents