Как получить пользовательские данные для обработчика сигнала aio в Mac OS X - PullRequest
4 голосов
/ 25 февраля 2011

Я пытаюсь использовать функции aio_ * для асинхронного ввода-вывода файлов в Mac OS X, но у меня возникают проблемы с получением той или иной формы пользовательских данных в обработчике сигналов.

Это код, который устанавливает операцию:

class aio_context {
public:
    aio_context(int fildes, boost::uint64_t offset,
        const MyBufferClassPtr &buffer)
    {
        // The aiocb struct must be zeroed
        memset(&m_aiocb, 0, sizeof(struct aiocb));

        // Set what to do
        m_aiocb.aio_fildes = fildes;
        m_aiocb.aio_buf = buffer->data();
        m_aiocb.aio_nbytes = buffer->size();
        m_aiocb.aio_offset = offset;

        // Set notification
        m_aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
        m_aiocb.aio_sigevent.sigev_signo = SIGUSR1;

        // ATTEMPT TO SET A VALUE THAT CAN BE READ IN THE HANDLER
        m_aiocb.aio_sigevent.sigev_value.sival_ptr = this;
    }

    struct aiocb* GetAiocbp()
    {
        return &m_aiocb;
    }

private:
    struct aiocb m_aiocb;
    // Some more context here
};

Затем он вызывается откуда-то еще, как это:

aio_context *ctx = new aio_context(file_descriptor, offset, data);
// set some more context here
int ret = aio_write(ctx->GetAiocbp());
if (0 != ret) {
    // throw something
}

Моя настройка обработки сигнала выглядит следующим образом:

sigemptyset(&m_CurrentSIGHandler.sa_mask);
m_CurrentSIGHandler.sa_sigaction = aio_completion_handler;
m_CurrentSIGHandler.sa_flags = SA_SIGINFO;
sigaction(SIGUSR1, &m_CurrentSIGHandler, &m_PreviousSIGHandler);

и фактический обработчик, подобный этому:

void aio_completion_handler(int signo, siginfo_t *info, void *context)
{
    if (info->si_signo == SIGUSR1) {
        // Get the aio operation
        aio_context *ctx = static_cast<aio_context *>(info->si_value.sival_ptr);

        // THIS ASSERT ALWAYS FAILS - ctx IS NULL
        assert(ctx);

        // next check aio_error and aio_return using the aicb member of the ctx
        // ...
    }
}

Таким образом, проблема в том, что si_value.sival_ptr всегда равен NULL в обработчике сигнала, а не является указателем aio_context, который я установил в структуре aiocb. Должно быть, я что-то неправильно понял, как это сделать, поэтому кто-нибудь может сказать мне, что я делаю неправильно?

Я работаю на MacOSX 10.6, но я (по крайней мере, пытаюсь) компилировать для 10.5, если это имеет значение.

Кроме того, ответ на этот вопрос , кажется, указывает на то, что AIO следует полностью игнорировать - действительно ли это так?

Обновление:

Я обнаружил, что у кого-то еще возникла такая же проблема в http://lists.apple.com/archives/darwin-dev/2008/Oct/msg00054.html.

Я также рассмотрел код ядра на http://www.opensource.apple.com/source/xnu/xnu-1504.9.26/bsd/kern/kern_aio.c и, если я правильно понял, sigev_value действительно полностью игнорируется. Я действительно в недоумении от того, что ожидаемое использование функций aio_ * в Mac OS X. Это не тот случай, когда их можно использовать как описано выше. Я что-то не так понял или функции aio_ * тупик для моего варианта использования?

1 Ответ

4 голосов
/ 15 марта 2011

Mac OS X не поддерживает сигналы реального времени ([RTS] в спецификации posix ), то есть раздел POSIX, который добавляет указатели пользовательских данных к сигналам.Это делает Mac OS X очень сложным для эффективного использования с AIO.Единственный вариант - пройтись по всем выдающимся работам и справиться с выполненными.

...