aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2021-10-11 13:49:31 -0700
committerTrumeet <yuuta@yuuta.moe>2021-10-11 13:49:31 -0700
commit5eb340686e89c77411dc9c2b301db02b69739676 (patch)
tree522d49e2133430f54bf2cc31e45c9ab6b7eaaaaa
parent251be34bea8d9c0a9f95f4cb2ade71b4c54b6d9b (diff)
downloadeasy-tg-5eb340686e89c77411dc9c2b301db02b69739676.tar
easy-tg-5eb340686e89c77411dc9c2b301db02b69739676.tar.gz
easy-tg-5eb340686e89c77411dc9c2b301db02b69739676.tar.bz2
easy-tg-5eb340686e89c77411dc9c2b301db02b69739676.zip
safely close TDLib in the example
-rw-r--r--example.c58
1 files changed, 56 insertions, 2 deletions
diff --git a/example.c b/example.c
index d8b268d..4a2fa1c 100644
--- a/example.c
+++ b/example.c
@@ -1,9 +1,10 @@
+#define _POSIX_C_SOURCE 200809L
#include "easy-tg.h"
#include <stdio.h>
#include <unistd.h>
#include <string.h>
-
-/* In this example we are not closing TDLib properly. In a real-world program, you need to call tg_close() to make a close request to TDLib (any thread is OK), and wait for the TG_CLOSED response. */
+#include <pthread.h>
+#include <signal.h>
static void read_input(const char *prompt, char *buf, unsigned int len)
{
@@ -34,9 +35,57 @@ static void run()
printf("%s\n", tg_update_type);
}
+static void *main_sighandler(void *arg)
+{
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ int r = 0;
+ sigset_t *set = arg;
+ int sig;
+ while(true)
+ {
+ r = sigwait(set, &sig);
+ if(r)
+ {
+ fprintf(stderr, "Cannot call sigwait(): %d.\n", r);
+ goto cleanup;
+ }
+ switch(sig)
+ {
+ case SIGINT:
+ case SIGTERM:
+ printf("Received SIGINT or SIGTERM, asking TDLib to close.\n");
+ tg_close();
+ goto cleanup;
+ }
+ }
+ goto cleanup;
+cleanup:
+ pthread_exit(NULL);
+ return NULL;
+}
+
int main(int argc, char **argv)
{
+ bool sighandler_setup = false;
+ pthread_t thread_sighandler;
int r = 0;
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGINT);
+ r = pthread_sigmask(SIG_BLOCK, &set, NULL);
+ if(r)
+ {
+ fprintf(stderr, "Cannot call pthread_sigmask(): %d\n", r);
+ goto cleanup;
+ }
+ r = pthread_create(&thread_sighandler, NULL, &main_sighandler, &set);
+ if(r)
+ {
+ fprintf(stderr, "Cannot call pthread_create(): %d\n", r);
+ goto cleanup;
+ }
+ sighandler_setup = true;
r = tg_init();
if(r) goto cleanup; /* Fetal errors encountered. */
while(1)
@@ -135,5 +184,10 @@ destroy:
tg_destroy();
goto cleanup;
cleanup:
+ if(sighandler_setup)
+ {
+ pthread_cancel(thread_sighandler);
+ pthread_join(thread_sighandler, NULL);
+ }
return r;
}