Skip to content

Custom loop

Julien edited this page Jan 18, 2023 · 3 revisions

Introduction

twirc_loop() is a very convenient way to run an endless loop until the connection to the Twitch server is being terminated. However, when developing a somewhat sophisticated application, you might want more fine-grained control and do some other things in your main loop. This can easily be achieved as explained in the following section.

twirc_tick()

twirc_loop() is actually very simple, it basically just calls twirc_tick() in a loop. Let's look at the latter:

int twirc_tick(twirc_state_t *s, int timeout);

As usual, the function takes the twirc state. In addition, it asks for a timeout. This controls for how long, in milliseconds, twirc_tick() will wait for IRC messages to come in until it gives control back to you. It will return 0 if everything went well, -1 if the connection to the server has been lost or a serious error has occurred, both of which are good reasons to end the loop and take some action.

If you wanted to grant twirc_tick() 1 second time in each iteration of your main loop, you could do the following:

while (twirc_tick(s, 1000) == 0)
{
    // Do all the things!
}
// Loop ended: we're either disconnected or ran into an error!

A simple example of how this allows you more control over your program is by introducing a flag that allows you to end the loop whenever you want. The flag could be flipped when the user wants to exit the program. You can then do this:

int running = 1;
while (twirc_tick(s, 1000) == 0 && running == 1)
{
    // Do all the things!
    // Some of these things might cause running to be set to 0.
}
// Loop ended: we're either disconnected or ran into an error 
// or the running flag has been set to 0.

And that's pretty much all there is to it.

Signal handling

twirc_tick() uses epoll_pwait() internally. If epoll's polling mechanism catches a signal, it will interrupt and return with an error message, causing twirc_tick() to return -1 as well. However, twirc_tick() instruct epoll_pwait() to block all signals that would be ignored by default. This means you can safely catch a SIGWINCH, for example, without twirc_tick() returning with an error. However, signals that would cause program termination or interruption by default will cause twirc_tick() to error out. You can check if a signal was the reason for it by checking if twirc_get_last_error() equals TWIRC_ERR_EPOLL_SIG.

Note: when twirc_tick() returns because of a signal interruption, the connection to the Twitch server is most likely still up and running! You can confirm this with twirc_is_connected(). It is up to you to decide whether you want to disconnect at this point or restart your event loop after taking whatever action you deem necessary to handle the signal. An interesting example case is SIGSTOP, which works in conjuction with SIGCONT to signal to a process to (temporarily) halt execution and, maybe, continue at a later point. You could now end your program, but you could also disconnect and re-connect once you catch a SIGCONT. Alternatively, you could even keep the connection alive if you have reason to believe that you will receive a SIGCONT shortly after.

Clone this wiki locally