Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Общие вопросы > boost::signals2::connection


Автор: kotmatroskin55 08.12.15, 07:34
День добрый. Такой вопрос. Есть два неких процесса, под линуксом, который общаются посредством IPC. Один посылает сообщения в очередь. второй их принимает. Причем он их действительно принимает, ибо
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    ipcs -q
показывает содержащиеся в очереди сообщения, если второй процесс не запущен. А дебаги в приемнике показывают, что сообщение действительно пришло. Дальше начинается самое интересное: в приемнике используется бустовский коннект. вот он, почему-то и не срабатывает. Ниже код отправки, код приема, и код обработки. Вся беда в том, что с бустом никогда серьезно не работал. И для меня, на данный момент, это вынос мозга. Сложность еще в том, что сборка производится на ПК, а запуск на приборе с ARM архитектурой, то есть отладка только дебагами. Нет, я конечно попробовал gdb server, но он для других целей здесь годится.
код отправки:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    int  p347_HwClient::setBacklightLevel(const unsigned short percent)
    {
        int ret = 0;
        if (server_queue_id < 0) {
            logMessage(LOG_LEVEL_CRITICAL,"No connection to message server\n");
            ret = -ENXIO;
        } else {
            t_msg_from_hwmon_client tmfc;
            //      boa
            tmfc.type           = p347_MSGTYPE_HWMON_BRIGHTNESS;
            tmfc.do_shutdown    = false;
            tmfc.do_reboot      = false;
            tmfc.do_suspend     = false;
            tmfc.backlightLevel = percent;
            ret = sendMessageToIPCServer(&tmfc,sizeof(t_msg_from_hwmon_client));
     
        }
        printf("p347_HwClient::setBacklightLevel ret = %d \n ",ret);
        return ret;
    }
    //////////////////////////////////////////////////////////////////////////////
    int p347_IPCClient::sendMessageToIPCServer(void* data, int data_len) {
        printf("data_len = %d \n",data_len);
        if ((data == NULL) || (data_len < 1)) {
            return -EINVAL;
        }
        if (server_queue_id < 0) {
            return -ENXIO;
        }
     
        t_p347_ipc_msg msg;
        msg.mtype = p347_DEFAULT_MSG_TYPE + 10;
        memcpy(&msg. mtext[0], data, data_len);
     
        int ret = msgsnd(server_queue_id, &msg, data_len, 0);
        printf("sendMessageToIPCServer,server_queue_id = %d, ret = %d \n ",server_queue_id,ret);
        if (ret < 0) {
            ret = -errno;
            logMessage(LOG_LEVEL_CRITICAL,"msgsnd fails with %d\n",ret);
        } else {
            printf("send message successfully ret = %d \n",ret);
        }
        return ret;
    }

Код приемника:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void p347_MsgServer::Execute(void) {
        int ret;
     
        //printf("msgserver resume\n");
     
        t_p347_ipc_msg msg;
        msg.mtype = p347_DEFAULT_MSG_TYPE;
     
        ev_end->ResetEvent();
        int count = 0;
        while (!Terminated) {
            ++count;
            memset(&msg.mtext[0],0,p347_MAX_IPC_MSG_LEN);
            ret = msgrcv(queue_id,&msg,p347_MAX_IPC_MSG_LEN,0,0);
            printf("ret = msgrcv(queue_id,&msg,p347_MAX_IPC_MSG_LEN,0,0) %d count = %d \n",ret,count);
            //logMessage(LOG_LEVEL_MAIN,"msgrcv ret %d\n",ret);
     
            if (ret > 0) {
                printf("ret > 0 \n");
                printf("sig_data(ret,(void *)&msg.mtext[0]);\n");
                sig_data(ret,(void *)&msg.mtext[0]);
    //boost::signals2::signal<void (int data_len, void* data)> sig_data;
            } else {
                printf("ret <= 0\n");
                usleep(1000);
            }
        }
        
        ev_end->SetEvent();
        logMessage(LOG_LEVEL_MAIN,"execution terminated\n");
    }

а вот здесь, собственно говоря, соединение
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    void p347_HwService::Execute(void) {
        c_data = mserver->sig_data.connect(boost::bind(&p347_HwService::onIncomingMessage,
                                                       this, _1, _2));
    // где boost::signals2::connectionc_data;

Там еще много всего, но до отправки сигнала я могу проследить ход событий. Дальше нет. Отсюда, наверное, логично предположить, что сигнал не отправляется. Но не факт. В общем нужен совет. Проект огромный, кода там тыщ семьдесят, автора нет. Буду рад любому совету.

Автор: Qraizer 08.12.15, 20:03
Я не увидел здесь никакого криминала. Могу только предположить, что список коннектов по некой причине оказался пуст.

Автор: kotmatroskin55 09.12.15, 04:00
Цитата Qraizer @
Могу только предположить, что список коннектов по некой причине оказался пуст.

А есть ли возможность посмотреть этот список коннектов каким либо образом?

Автор: Qraizer 09.12.15, 06:51
Ну, там есть метод boost::signals2::signal::num_slots(). А вот на предмет пройтись по списку, такого нету.
Но каждый вызов boost::signals2::signal::connect() возвращает уникальный экземпляр boost::signals2::connection, у которого есть метод connected(). Если ты говоришь, что "там много всего", маловероятно, но возможно, что слот становится невалидным по каким-то причинам, например, его адресат умер по естественным причинам.

Автор: kotmatroskin55 04.01.16, 05:37
Вопрос решился, причем достаточно просто: все работало, причина была в неправильной организации взаимодействия между потоками, я просто не доходил до отправки сигнала. Искал долго, т.к. удаленная отладка занятие достаточно интересное.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)