Синхронизация функций обратного вызова ALooper - PullRequest
1 голос
/ 09 января 2020

У меня есть ALooper с 2 каналами и 2 функциями обратного вызова в C,

mainThreadLooper = ALooper_forThread(); // get looper for this thread
ALooper_acquire(mainThreadLooper); // add reference to keep object alive
pipe(messagePipe); 
pipe(commandPipe);

ALooper_addFd(mainThreadLooper, messagePipe[0],
        0, ALOOPER_EVENT_INPUT, looperCallback, NULL);
ALooper_addFd(mainThreadLooper, commandPipe[0],
        0, ALOOPER_EVENT_INPUT, commandLooperCallback, NULL);

, и вот 2 функции обратного вызова, которые работают правильно

static int commandLooperCallback(int fd, int events, void* data){
    LOGD("command pipe callback");
    wchar_t c;
    read(fd, &c,sizeof(c));
    if(running){
        if(c == 0){
            return 1;
        }
        if(c == CLEAR_SCREEN){
            LOGD("clear screen");
            clearScreen();
            return 1;
        }
    }

    return 1;
}


static int looperCallback(int fd, int events, void* data) {
    //char msg[100];
    wchar_t msg[100];

    int length = read(fd, &msg,sizeof(msg)); //99); // read message from pipe
    LOGD("string recieved: %ls", msg);
    char str[length];
    wcstombs(str,msg,length);
    LOGD("char string %s", str);
  //msg[length] = 0;
    if(running){
        printToTextView(str);
    }

    //LOGD("returning from looper callback");
    return 1; // continue listening for events
}

проблема что они вызываются не по порядку в моем коде, в результате чего, скажем, clearScreen() в другое время, чем когда я писал в каналы в коде.

Если кто-нибудь знает, как синхронизировать эти обратные вызовы Alooper, пожалуйста, заполните Я в. Я использую ALooper, потому что я использую pthread в C, и запись в каналы происходит из pthread, и Alooper - это способ, которым я перезваниваю в поток пользовательского интерфейса в android

благодарю ты за свое время

1 Ответ

0 голосов
/ 10 января 2020

вот как я это сделал.

в моем файле с обратными вызовами сделать

_Atomic bool command = false;
_Atomic bool writing = false;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

затем в свои обратные вызовы я положил

static int commandLooperCallback(int fd, int events, void* data){
    if(!command){
        return 1;
    }
    LOGD("command pipe callback");
    wchar_t c;
    read(fd, &c,sizeof(c));
    if(running){
        if(c == 0){
            return 1;
        }
        if(c == CLEAR_SCREEN){
            LOGD("clear screen");


            clearScreen();
            command = false;
            pthread_mutex_lock(&lock);
            pthread_cond_signal(&cond);
            pthread_mutex_unlock(&lock);
            //wait = false;
            return 1;
        }
    }

    return 1;
}

и

static int looperCallback(int fd, int events, void* data) {
    //char msg[100];
    if(!writing){
        return 1;
    }
    wchar_t msg[100];

    int length = read(fd, &msg,sizeof(msg)); //99); // read message from pipe
    LOGD("string recieved: %ls", msg);
    char str[length];
    wcstombs(str,msg,length);
    LOGD("char string %s", str);
  //msg[length] = 0;
    if(running){
        printToTextView(str);
    }
    writing = false;
    pthread_mutex_lock(&lock);
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&lock);
    //LOGD("returning from looper callback");
    return 1; // continue listening for events
}

затем в зависимости от того, какой канал я писал в этот

//and opposite for commandPipe and making command bool true
write(messagePipe[1],NameBuffer, sizeof(NameBuffer));//strlen(s));
    writing = true;
    pthread_mutex_lock(&lock);
    pthread_cond_wait(&cond, &lock);
    pthread_mutex_unlock(&lock);
...