0

I wrote the following code to implement a periodic thread terminated when someone presses escape. The result is a periodic thread that continues also after i pressed escape. Can you tell me where is the error please? The compiler compiles without any error and warning. Before reading the code jump to EDIT below.

#include <stdio.h>
#include <pthread.h>
#include <allegro.h>
#include <time.h>
 
void    *task(void *p);
void    time_add_ms(struct timespec *t, int ms);
 
int main()
{
int tret;
int a = 1;
 
    allegro_init();
    install_keyboard();
 
    tret = pthread_create(&tid, NULL, task, (void*)&a);
 
    pthread_join(tid, NULL);
 
    printf("Thread1 returns %d\n", tret);
    allegro_exit();
    return 0;
}
 
 
/* Sommare quantità temporale espressa in ms al tempo nella struttura timespec */
void    time_add_ms(struct timespec *t, int ms)
{
    t->tv_sec += ms / 1000;
    t->tv_nsec += (ms % 1000) * 1000000;
 
    if (t->tv_nsec > 1000000000){
        t->tv_nsec -= 1000000000;
        t->tv_sec += 1;
    }
}
 
/* Funzione da trasformare in task */
void    *task(void *p)
{
struct timespec t;
int period = 100;
int *pi;
char scan = 0;  
 
    clock_gettime(CLOCK_MONOTONIC, &t);
    time_add_ms(&t, period);
    pi = (int *)p;
 
    while (scan != KEY_ESC) {
        if (keypressed()) scan = readkey() >> 8;
        printf("This is TASK %d\n", *pi);
 
        clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
        time_add_ms(&t, period);
    }
}

EDIT: maybe i found the problem, when i press escape, it prints the symbol ^, so the compiler or allegro doen't recognize the esc key.

Gennaro Arguzzi
  • 528
  • 5
  • 13
  • I suggest you change the key to some other key, to see if that key works any different. Also, I suggest you add some `fprintf` calls to `stderr` for debugging purposes. The stream `stderr` is better than `stdout` for debbuging purposes, because it is normally not buffered. A call to `printf` is equivalent to a `fprintf` call to `stdout`. – Andreas Wenzel Jun 20 '20 at 14:47
  • I suggest you make such an `fprintf` call to `stderr` as soon as the thread detects the keypress. That way, you can test if the keypress is being detected properly. – Andreas Wenzel Jun 20 '20 at 14:54
  • Hello @AndreasWenzel it's the first time i'm using this libraries and C (i did only a small course on C++)...maybe the problem is the keypressed because if i write the command "printf("Key in the buffer");" inside if (keypressed()), it doesn't print anything – Gennaro Arguzzi Jun 20 '20 at 15:01
  • I suggest you replace `printf("Key in the buffer");` with `fprintf( stderr, "Key in the buffer" );` for the reasons stated in my previous comments. It could be that you are seeing nothing because `stdout` (which is used by `printf`) is [buffered](https://stackoverflow.com/q/1716296/12149471). That's why an `fprintf` call to `stderr` is more reliable. – Andreas Wenzel Jun 20 '20 at 15:04
  • @AndreasWenzel i tried with fprintf, but the result is the same: when i press a key, the string is not printed. – Gennaro Arguzzi Jun 20 '20 at 15:49
  • In your previous comment, you stated that you used `fprintf`, but not whether you used `stdout` or `stderr`. Using `stdout` would make it equivalent to `printf`. If you used `stderr` as I recommended to you, then this likely means that the line of code is never executed. You might want to set a breakpoint in a debugger to verify this. – Andreas Wenzel Jun 20 '20 at 16:54
  • @AndreasWenzel i used fprintf( stderr, "Key in the buffer" ); – Gennaro Arguzzi Jun 20 '20 at 17:04

1 Answers1

0

This is not exactly finding the error, but I think it is what you want (more details here)

If you add following code to your main(), this will disable canonical mode, which will basically enable you to get characters immediately without waiting for a '\n' or EOF (or enter keypress in short) (already explained in the link above):

#include <termios.h>           
#include <unistd.h>    

int main(){
    static struct termios oldt, newt;
    tcgetattr( STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON);
    tcsetattr( STDIN_FILENO, TCSANOW, &newt);  
    // rest of your code
}

And the thread loop here (I've changed it a little bit)

while (1) {
    printf("This is TASK %d\n", *pi);
    clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
    time_add_ms(&t, period);
    if(getchar()==27) break;
}
grizzly
  • 237
  • 2
  • 13
  • 1
    Hello @grizzly, thank you for your answer...i need to hold the above format (i "cannot" add code) to satisfy someone. This someone uses the same strategy i used, but in my case there is something wrong. – Gennaro Arguzzi Jun 20 '20 at 15:53