summaryrefslogtreecommitdiff
path: root/pjlib/src/pj++/proactor.hpp
blob: d5dc03674ee03c893d0d202da7027d93a751a2f0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/* $Header: /pjproject/pjlib/src/pj++/proactor.hpp 3     8/24/05 10:29a Bennylp $ */
#ifndef __PJPP_EVENT_HANDLER_H__
#define __PJPP_EVENT_HANDLER_H__

#include <pj/ioqueue.h>
#include <pj++/pool.hpp>
#include <pj++/sock.hpp>
#include <pj++/timer.hpp>

class PJ_Proactor;


class PJ_Event_Handler
{
    friend class PJ_Proactor;
public:
    PJ_Event_Handler();
    virtual ~PJ_Event_Handler();

    virtual pj_oshandle_t get_handle() = 0;

    bool read(void *buf, pj_size_t len);
    bool recvfrom(void *buf, pj_size_t len, PJ_INET_Addr *addr);
    bool write(const void *data, pj_size_t len);
    bool sendto(const void *data, pj_size_t len, const PJ_INET_Addr &addr);
#if PJ_HAS_TCP
    bool connect(const PJ_INET_Addr &addr);
    bool accept(PJ_Socket *sock, PJ_INET_Addr *local=NULL, PJ_INET_Addr *remote=NULL);
#endif

protected:
    //
    // Overridables
    //
    virtual void on_timeout(int data) {}
    virtual void on_read_complete(pj_ssize_t bytes_read) {}
    virtual void on_write_complete(pj_ssize_t bytes_sent) {}
#if PJ_HAS_TCP
    virtual void on_connect_complete(int status) {}
    virtual void on_accept_complete(int status) {}
#endif

private:
    PJ_Proactor	     *proactor_;
    pj_ioqueue_key_t *key_;
    pj_timer_entry    timer_;
    int		      tmp_recvfrom_addr_len;

public:
    // Internal IO Queue/timer callback.
    static void timer_callback( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry);
    static void read_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_read);
    static void write_complete_cb(pj_ioqueue_key_t *key, pj_ssize_t bytes_sent);
    static void accept_complete_cb(pj_ioqueue_key_t *key, int status);
    static void connect_complete_cb(pj_ioqueue_key_t *key, int status);
};

class PJ_Proactor
{
public:
    static PJ_Proactor *create(PJ_Pool *pool, pj_size_t max_fd, 
			       pj_size_t timer_entry_count, unsigned timer_flags=0);

    void destroy();

    bool register_handler(PJ_Pool *pool, PJ_Event_Handler *handler);
    void unregister_handler(PJ_Event_Handler *handler);

    static bool schedule_timer( pj_timer_heap_t *timer, PJ_Event_Handler *handler,
				const PJ_Time_Val &delay, int id=-1);
    bool schedule_timer(PJ_Event_Handler *handler, const PJ_Time_Val &delay, int id=-1);
    bool cancel_timer(PJ_Event_Handler *handler);

    bool handle_events(PJ_Time_Val *timeout);

    pj_ioqueue_t *get_io_queue();
    pj_timer_heap_t *get_timer_heap();

private:
    pj_ioqueue_t *ioq_;
    pj_timer_heap_t *th_;

    PJ_Proactor() {}
};

#endif	/* __PJPP_EVENT_HANDLER_H__ */