Другие способы использования функции poll () (пользовательское пространство)? - PullRequest
2 голосов
/ 14 августа 2011

Я пытаюсь найти лучшие методы для обработки событий опрашиваемого сокета (fd). Я застрял на этом, чтобы использовать функцию poll() с другим pollfd следующим образом:

#define out std::cout
#define el std::endl
#define line(string) out<<string<<el
class int_t
{
    private:
        int _int;
        int _owner;
    public:
        operator int() const;
        int_t();
        int_t(const int& in);
        int_t& operator=(const int& in);
        int_t operator|(const int& in) const;
        int_t operator&(const int& in) const;
        /*
        ...
        ...
        */
        void setowner(const int& fd);
        ~int_t();
};
int_t::operator int() const
{
    return this->_int;
}
int_t::int_t()
{
    this->_int = 0;
    this->_owner = 0;
}
int_t::int_t(const int& in)
{
    this->_int = in;
    this->_owner = 0;
}
int_t& int_t::operator=(const int& in)
{
    line("operator '=' called"<<" owner:"<<this->_owner);
    this->_int = in;
    return *this;
}
int_t int_t::operator|(const int& in) const
{
    line("operator '|' called"<<" owner:"<<this->_owner);
    return (this->_int|in);
}
int_t int_t::operator&(const int& in) const
{
    line("operator '&' with arg called"<<" owner:"<<this->_owner);
    return (this->_int&in);
}
/*
...
...
*/
void int_t::setowner(const int& fd)
{
    this->_owner = fd;
}
int_t::~int_t()
{
    this->_int = 0;
}
struct pollfd_other
{
    // Valgrind returns me an error when i changing the type of the `revent` only
    // but when i changing the type of the `event` and `revent` works without error
    // and `poll()` gets the flags normally from the `event` if ill put for example
    // a `POLLIN` flag.
    int fd;
    int_t events;
    int_t revents;
    void setowner(const int& pollfdowner){
        this->fd = pollfdowner;
        this->revents.setowner(pollfdowner);
    } 
};
int main(int argc,char* argv[])
{
    Server server;
    pollfd_other pfd[1];
    pfd[0].setowner(server.socket);
    ::poll(reinterpret_cast<pollfd*>(&pfd),1,-1);
    // ...
}

class int_t очень хорошо работает как целое число и struct pollfd_other ... но poll() не обращается к нему как к классу для вызова операторов ...
Цель этого - создать поток, когда оператор будет вызываться для revents члена struct pollfd_other.
Есть ли другой способ сделать что-то подобное? Предложения приветствуются ...

Ответы [ 2 ]

3 голосов
/ 14 августа 2011

Это выглядит очень запутанным.Если вы хотите инкапсулировать функциональность опроса в объекте, не инкапсулируйте int, инкапсулируйте опрос.Примерно так:

class poller_callback {
    public:
        void handle_pollin(int fd) = 0;
};

class poller {
    public:
        poller(const vector<int>& fds);
        void do_poll(const poller_callback& c)
        {
            // poll(&pfd, ...);
            if(fd[i].revents & POLLIN) {
                c.handle_pollin(fd[i].fd);
            }
        }
};

int main(void)
{
    my_poller_callback my_handler;
    // get fds
    poller my_poller(fds);
    do_poll(my_handler);
    // ...
    return 0;
}

Вот как я это сделаю.Имейте класс, который инкапсулирует poll(), который параметризован на том, что он должен делать на событиях.poller_callback - это интерфейс для объектов, которые обрабатывают события.Затем вы можете написать my_poller_callback, который в handle_pollin создает поток.

2 голосов
/ 14 августа 2011

В Linux я рекомендую epoll (http://kovyrin.net/2006/04/13/epoll-asynchronous-network-programming/, справочные страницы).Это намного быстрее, чем poll / select и проще в использовании, потому что вы можете назначить указатель для каждого обработанного дескриптора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...