summaryrefslogtreecommitdiffstats
path: root/src/events.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/events.h')
-rw-r--r--src/events.h840
1 files changed, 840 insertions, 0 deletions
diff --git a/src/events.h b/src/events.h
new file mode 100644
index 0000000..c13e9c0
--- /dev/null
+++ b/src/events.h
@@ -0,0 +1,840 @@
+/*
+ Copyright (C) 2005-2009 Michel de Boer <michel@twinklephone.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/**
+ * @file
+ * Threads communicate by passing events via event queues.
+ */
+
+#ifndef _EVENTS_H
+#define _EVENTS_H
+
+#include <queue>
+#include "protocol.h"
+#include "timekeeper.h"
+#include "stun/stun.h"
+#include "audio/audio_codecs.h"
+#include "parser/sip_message.h"
+#include "sockets/socket.h"
+#include "sockets/url.h"
+#include "threads/mutex.h"
+#include "threads/sema.h"
+
+using namespace std;
+
+// Forward declarations
+class t_userintf;
+
+/** Different types of events. */
+enum t_event_type {
+ EV_QUIT, /**< Generic quit event */
+ EV_NETWORK, /**< Network event, eg. SIP message from/to network */
+ EV_USER, /**< User event, eg. SIP message from/to user */
+ EV_TIMEOUT, /**< Timer expiry */
+ EV_FAILURE, /**< Failure, eg. transport failure */
+ EV_START_TIMER, /**< Start timer */
+ EV_STOP_TIMER, /**< Stop timer */
+ EV_ABORT_TRANS, /**< Abort transaction */
+ EV_STUN_REQUEST, /**< Outgoing STUN request */
+ EV_STUN_RESPONSE, /**< Received STUN response */
+ EV_NAT_KEEPALIVE, /**< Send a NAT keep alive packet */
+ EV_ICMP, /**< ICMP error */
+ EV_UI, /**< User interface event */
+ EV_ASYNC_RESPONSE, /**< Response on an asynchronous question */
+ EV_BROKEN_CONNECTION, /**< Persitent connection to SIP proxy broken */
+ EV_TCP_PING, /**< Send a TCP ping (double CRLF) */
+};
+
+/** Abstract parent class for all events */
+class t_event {
+public:
+ virtual ~t_event() {}
+
+ /** Get the type of this event. */
+ virtual t_event_type get_type(void) const = 0;
+};
+
+
+/**
+ * Generic quit event.
+ * The quit event instructs a thread to exit gracefully.
+ */
+class t_event_quit : public t_event {
+public:
+ virtual ~t_event_quit();
+ virtual t_event_type get_type(void) const;
+};
+
+
+/**
+ * Network events.
+ * A network event is a SIP message going from the transaction manager
+ * to the network or v.v.
+ */
+class t_event_network : public t_event {
+private:
+ /** The SIP message. */
+ t_sip_message *msg;
+
+public:
+ unsigned int src_addr; /**< Source IP address of the SIP message (host order). */
+ unsigned short src_port; /**< Source port of the SIP message (host order). */
+ unsigned int dst_addr; /**< Destination IP address of the SIP message (host order). */
+ unsigned short dst_port; /**< Destination port of the SIP message (host order). */
+ string transport; /**< Transport protocol */
+
+ /**
+ * Constructor.
+ * The event will keep a copy of the SIP message.
+ * @param m [in] The SIP message.
+ */
+ t_event_network(t_sip_message *m);
+
+ ~t_event_network();
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the SIP message.
+ * @return Pointer to the SIP message inside this event.
+ */
+ t_sip_message *get_msg(void) const;
+};
+
+
+/**
+ * User events.
+ * A user event is a SIP message going from the user to the
+ * transaction manager or v.v.
+ */
+class t_event_user : public t_event {
+private:
+ t_sip_message *msg; /**< The SIP message. */
+ unsigned short tuid; /**< Transaction user id. */
+ unsigned short tid; /**< Transaction id. */
+
+ /**
+ * Transaction id that is the target of the CANCEL message.
+ * Only set if tid is a CANCEL transaction and the event
+ * is sent towards the user.
+ */
+ unsigned short tid_cancel_target;
+
+ /** User profile of the user sending/receiving the SIP message. */
+ t_user *user_config;
+
+public:
+ /** Constructor.
+ * @param u [in] User profile.
+ * @param m [in] SIP message
+ * @param _tuid [in] Transaction user id associated with this message.
+ * @param _tid [in] Transaction id of the transaction for this message.
+ */
+ t_event_user(t_user *u, t_sip_message *m, unsigned short _tuid,
+ unsigned short _tid);
+
+ /** Constructor for CANCEL request towards the user.
+ * @param u [in] User profile.
+ * @param m [in] SIP message.
+ * @param _tuid [in] Transaction user id associated with this message.
+ * @param _tid [in] Transaction id of the transaction for this message.
+ * @param _tid_cancel_target [in] Id of the target transaction of a CANCEL request.
+ */
+ t_event_user(t_user *u, t_sip_message *m, unsigned short _tuid,
+ unsigned short _tid, unsigned short _tid_cancel_target);
+
+ ~t_event_user();
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the SIP message.
+ * @return Pointer to the SIP message inside this event.
+ */
+ t_sip_message *get_msg(void) const;
+
+ /** Get transaction user id. */
+ unsigned short get_tuid(void) const;
+
+ /** Get transaction id. */
+ unsigned short get_tid(void) const;
+
+ /** Get the CANCEL target transaction id. */
+ unsigned short get_tid_cancel_target(void) const;
+
+ /**
+ * Get the user profile.
+ * @return Pointer to the user profile inside the event.
+ */
+ t_user *get_user_config(void) const;
+};
+
+
+/**
+ * Time out events.
+ * Expiration of a timer is signalled by a time out event.
+ */
+class t_event_timeout : public t_event {
+private:
+ /**
+ * The epxired timer.
+ * @note Timer pointer will be deleted upon destruction of the object.
+ */
+ t_timer *timer;
+
+public:
+ /**
+ * Constructor.
+ * @param t [in] The expired timer.
+ * @note The event will keep a copy of the timer.
+ */
+ t_event_timeout(t_timer *t);
+
+ ~t_event_timeout();
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the timer from the event.
+ * @return The timer.
+ */
+ t_timer *get_timer(void) const;
+};
+
+/**
+ * Failure events.
+ */
+class t_event_failure : public t_event {
+private:
+ t_failure failure; /**< Type of failure. */
+
+ /**
+ * Indicates if the tid value is populated. If the tid value is not
+ * populated, then the branch and cseq_method are populated.
+ */
+ bool tid_populated;
+
+ unsigned short tid; /**< Id of transaction that failed. */
+
+ string branch; /**< Branch parameter of SIP message that failed. */
+ t_method cseq_method; /**< CSeq method of SIP message that failed. */
+public:
+ /**
+ * Constructor.
+ * @param f [in] Type of failure.
+ * @param _tid [in] Transaction id.
+ */
+ t_event_failure(t_failure f, unsigned short _tid);
+
+ /** Constructor */
+ t_event_failure(t_failure f, const string &_branch, const t_method &_cseq_method);
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the type of failure.
+ * @return Type of failure.
+ */
+ t_failure get_failure(void) const;
+
+ /**
+ * Get the transaction id.
+ * @return Transaction id.
+ */
+ unsigned short get_tid(void) const;
+
+ /** Get branch parameter. */
+ string get_branch(void) const;
+
+ /** Get CSeq method. */
+ t_method get_cseq_method(void) const;
+
+ /** Check if tid is populated. */
+ bool is_tid_populated(void) const;
+};
+
+
+/**
+ * Start timer event.
+ * A start timer event instructs the time keeper to start a timer.
+ */
+class t_event_start_timer : public t_event {
+private:
+ t_timer *timer; /**< The timer to start. */
+
+public:
+ /**
+ * Constructor.
+ * @param t [in] The timer to start.
+ */
+ t_event_start_timer(t_timer *t);
+
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the timer.
+ * @return Timer.
+ */
+ t_timer *get_timer(void) const;
+};
+
+
+/**
+ * Stop timer event
+ * A stop timer event instructs the time keeper to stop a timer.
+ */
+class t_event_stop_timer : public t_event {
+private:
+ /** Id of the timer to stop. */
+ unsigned short timer_id;
+
+public:
+ /**
+ * Constructor.
+ * @param id [in] Id of the timer to stop.
+ */
+ t_event_stop_timer(unsigned short id);
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the timer id.
+ * @return Timer id.
+ */
+ unsigned short get_timer_id(void) const;
+};
+
+
+/**
+ * Abort transaction event.
+ * With an abort transaction event, the requester asks the transaction
+ * manager to abort a pending transaction.
+ */
+class t_event_abort_trans : public t_event {
+private:
+ unsigned short tid; /**< Id of the transaction to abort. */
+public:
+ /**
+ * Constructor.
+ * @param _tid [in] Transaction id.
+ */
+ t_event_abort_trans(unsigned short _tid);
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get transaction id.
+ * @return Transaction id.
+ */
+ unsigned short get_tid(void) const;
+};
+
+
+/** STUN event types. */
+enum t_stun_event_type {
+ TYPE_STUN_SIP, /**< Request to open a port for SIP. */
+ TYPE_STUN_MEDIA, /**< Request to open a port for media. */
+};
+
+/**
+ * STUN request event.
+ */
+class t_event_stun_request : public t_event {
+private:
+ StunMessage *msg; /**< STUN request to send. */
+ unsigned short tuid; /**< Transaction user id. */
+ unsigned short tid; /**< Transaction id. */
+ t_stun_event_type stun_event_type; /**< Type of STUN event. */
+ t_user *user_config; /**< User profile associated with this request. */
+
+public:
+ unsigned int dst_addr; /**< Destination address of request (host order). */
+ unsigned short dst_port; /**< Destination port of request (host order). */
+ unsigned short src_port; /**< Source port for media event type (host order). */
+
+ /** Constructor. */
+ t_event_stun_request(t_user *u, StunMessage *m, t_stun_event_type ev_type,
+ unsigned short _tuid, unsigned short _tid);
+
+ ~t_event_stun_request();
+
+ t_event_type get_type(void) const;
+
+ /** Get STUN message. */
+ StunMessage *get_msg(void) const;
+
+ /** Get transaction user id. */
+ unsigned short get_tuid(void) const;
+
+ /** Get transaction id. */
+ unsigned short get_tid(void) const;
+
+ /** Get STUN event type. */
+ t_stun_event_type get_stun_event_type(void) const;
+
+ /** Get user profile. */
+ t_user *get_user_config(void) const;
+};
+
+
+/**
+ * STUN response event.
+ */
+class t_event_stun_response : public t_event {
+private:
+ StunMessage *msg; /**< STUN request to send. */
+ unsigned short tuid; /**< Transaction user id. */
+ unsigned short tid; /**< Transaction id. */
+
+public:
+ /** Constructor. */
+ t_event_stun_response(StunMessage *m, unsigned short _tuid,
+ unsigned short _tid);
+
+ ~t_event_stun_response();
+
+ t_event_type get_type(void) const;
+
+ /** Get STUN message. */
+ StunMessage *get_msg(void) const;
+
+ /** Get transaction user id. */
+ unsigned short get_tuid(void) const;
+
+ /** Get transaction id. */
+ unsigned short get_tid(void) const;
+};
+
+
+/**
+ * NAT keep alive event.
+ * Request to send a NAT keep alive message.
+ */
+class t_event_nat_keepalive : public t_event {
+public:
+ unsigned int dst_addr; /**< Destination address for keepalive (host order) */
+ unsigned short dst_port; /**< Destination port (host order) */
+
+ t_event_type get_type(void) const;
+};
+
+
+/**
+ * ICMP event.
+ * This event signals the reception of an ICMP error.
+ */
+class t_event_icmp : public t_event {
+private:
+ t_icmp_msg icmp; /**< The received ICMP message. */
+
+public:
+ /**
+ * Constructor.
+ * @param m [in] ICMP message.
+ */
+ t_event_icmp(const t_icmp_msg &m);
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the ICMP message.
+ * @return ICMP message.
+ */
+ t_icmp_msg get_icmp(void) const;
+};
+
+
+/** User interface callback types. */
+enum t_ui_event_type {
+ TYPE_UI_CB_DISPLAY_MSG, /**< Display a message */
+ TYPE_UI_CB_DTMF_DETECTED, /**< DTMF tone detected */
+ TYPE_UI_CB_SEND_DTMF, /**< Sending DTMF */
+ TYPE_UI_CB_RECV_CODEC_CHANGED, /**< Codec changed */
+ TYPE_UI_CB_LINE_STATE_CHANGED, /**< Line state changed */
+ TYPE_UI_CB_LINE_ENCRYPTED, /**< Line is now encrypted */
+ TYPE_UI_CB_SHOW_ZRTP_SAS, /**< Show the ZRTP SAS */
+ TYPE_UI_CB_ZRTP_CONFIRM_GO_CLEAR, /**< ZRTP Confirm go-clear */
+ TYPE_UI_CB_QUIT /**< Quit the user interface */
+};
+
+/** Display message priorities. */
+enum t_msg_priority {
+ MSG_NO_PRIO,
+ MSG_INFO,
+ MSG_WARNING,
+ MSG_CRITICAL
+};
+
+/**
+ * User interface event.
+ * Send a user interface callback to the user interface.
+ * Most callbacks are called directly as a function call.
+ * Sometimes an asynchronous callback is needed. That's where
+ * this event is used for.
+ */
+class t_event_ui : public t_event {
+private:
+ t_ui_event_type type; /**< User interface callback type. */
+
+ /** @name Parameters for call back functions */
+ //@{
+ int line; /**< Line number. */
+ t_audio_codec codec; /**< Audio codec. */
+ char dtmf_event; /**< DTMF event. */
+ bool encrypted; /**< Encryption indication. */
+ string cipher_mode; /**< Cipher mode (algorithm name). */
+ string zrtp_sas; /**< ZRTP SAS/ */
+ t_msg_priority msg_priority; /**< Priority of a display message. */
+ string msg; /**> Message to display. */
+ //@}
+
+public:
+ /**
+ * Constructor.
+ * @param _type [in] Type of callback.
+ */
+ t_event_ui(t_ui_event_type _type);
+
+ t_event_type get_type(void) const;
+
+ /** @name Set parameters for call back functions */
+ //@{
+ void set_line(int _line);
+ void set_codec(t_audio_codec _codec);
+ void set_dtmf_event(char _dtmf_event);
+ void set_encrypted(bool on);
+ void set_cipher_mode(const string &_cipher_mode);
+ void set_zrtp_sas(const string &sas);
+ void set_display_msg(const string &_msg, t_msg_priority &_msg_priority);
+ //@}
+
+ /**
+ * Call the callback function.
+ * @param user_intf [in] The user interface that receives the callback.
+ */
+ void exec(t_userintf *user_intf);
+};
+
+
+/**
+ * Asynchronous response event.
+ * A user interface can open an asynchronous message box to request
+ * information from the user. Via this event the user interface signals
+ * the response from the user.
+ */
+class t_event_async_response : public t_event {
+public:
+ /** Response type */
+ enum t_response_type {
+ RESP_REFER_PERMISSION /**< Response on permission to refer question */
+ };
+
+private:
+ t_response_type response_type; /**< Response type. */
+ bool bool_response; /**< Boolean response. */
+
+public:
+ /**
+ * Constructor.
+ * @param type [in] The response type.
+ */
+ t_event_async_response(t_response_type type);
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Set the boolean response.
+ * @param b [in] The response.
+ */
+ void set_bool_response(bool b);
+
+ /**
+ * Get response type.
+ * @return Response type.
+ */
+ t_response_type get_response_type(void) const;
+
+ /**
+ * Get boolean response.
+ * @return The response.
+ */
+ bool get_bool_response(void) const;
+};
+
+/**
+ * Broken connection event.
+ * A persistent connection to a SIP proxy is broken. With this event
+ * the transport layer signals the transaction layer that a connection
+ * is broken.
+ */
+class t_event_broken_connection : public t_event {
+private:
+ /** The user URI (AoR) that the connection was associated with. */
+ t_url user_uri_;
+
+public:
+ /** Constructor */
+ t_event_broken_connection(const t_url &url);
+
+ t_event_type get_type(void) const;
+
+ /**
+ * Get the user URI.
+ * @return The user URI.
+ */
+ t_url get_user_uri(void) const;
+};
+
+/**
+ * TCP ping event.
+ * Send a TCP ping (double CRLF).
+ */
+class t_event_tcp_ping : public t_event {
+private:
+ /** The user URI (AoR) for which the ping must be sent. */
+ t_url user_uri_;
+
+ unsigned int dst_addr_; /**< Destination address for ping (host order) */
+ unsigned short dst_port_; /**< Destination port (host order) */
+
+public:
+ /** Constructor */
+ t_event_tcp_ping(const t_url &url, unsigned int dst_addr, unsigned short dst_port);
+
+ t_event_type get_type(void) const;
+
+ /** @name Getters */
+ //@{
+ t_url get_user_uri(void) const;
+ unsigned int get_dst_addr(void) const;
+ unsigned short get_dst_port(void) const;
+ //@}
+};
+
+
+/**
+ * Event queue.
+ * An event queue is the communication pipe between multiple
+ * threads. Multiple threads write events into the queue and
+ * one thread reads the events from the queue and processes them
+ * Access to the queue is protected by a mutex. A semaphore is
+ * used to synchronize the reader with the writers of the queue.
+ */
+class t_event_queue {
+private:
+ queue<t_event *> ev_queue; /**< Queue of events. */
+ t_mutex mutex_evq; /**< Mutex to protect access to the queue. */
+ t_semaphore sema_evq; /**< Semephore counting the number of events. */
+
+ /**
+ * Semaphore to signal an interrupt.
+ * Will be posted when the interrupt method is called.
+ */
+ t_semaphore sema_caught_interrupt;
+
+public:
+ /** Constructor. */
+ t_event_queue();
+
+ ~t_event_queue();
+
+ /**
+ * Push an event into the queue.
+ * @param e [in] Event
+ */
+ void push(t_event *e);
+
+ /** Push a quit event into the queue. */
+ void push_quit(void);
+
+ /**
+ * Create a network event and push it into the queue.
+ * @param m [in] SIP message.
+ * @param ipaddr [in] Destination address of the message (host order).
+ * @param port [in] Port of the message (host order).
+ */
+ void push_network(t_sip_message *m, const t_ip_port &ip_port);
+
+ /**
+ * Create a user event and push it into the queue.
+ * The user event must be associated with a user profile.
+ * @param user_config [in] The user profile.
+ * @param m [in] SIP message.
+ * @param tuid [in] Transaction user id.
+ * @param tid [in] Transaction id.
+ */
+ void push_user(t_user *user_config, t_sip_message *m, unsigned short tuid,
+ unsigned short tid);
+
+ /**
+ * Create a user event and push it into the queue.
+ * The user event must be unrelated to a particular user profile.
+ * @param m [in] SIP message.
+ * @param tuid [in] Transaction user id.
+ * @param tid [in] Transaction id.
+ */
+ void push_user(t_sip_message *m, unsigned short tuid,
+ unsigned short tid);
+
+ /**
+ * Create a cancel event for a user.
+ * @param user_config [in] The user profile.
+ * @param m [in] SIP message.
+ * @param tuid [in] Transaction user id.
+ * @param tid [in] Transaction id.
+ */
+ void push_user_cancel(t_user *user_config, t_sip_message *m, unsigned short tuid,
+ unsigned short tid, unsigned short target_tid);
+
+ /**
+ * Create a cancel event for a user.
+ * @param m [in] SIP message.
+ * @param tuid [in] Transaction user id.
+ * @param tid [in] Transaction id.
+ */
+ void push_user_cancel(t_sip_message *m, unsigned short tuid,
+ unsigned short tid, unsigned short target_tid);
+
+ /**
+ * Create a timeout event and push it into the queue.
+ * @param t [in] The timer that expired.
+ */
+ void push_timeout(t_timer *t);
+
+ /**
+ * Create failure event and push it into the queue.
+ * @param f [in] Type of failure.
+ * @param tid [in] Transaction id of failed transaction.
+ */
+ void push_failure(t_failure f, unsigned short tid);
+
+ /**
+ * Create failure event and push it into the queue.
+ * @param f [in] Type of failure.
+ * @param branch [in] Branch parameter of failed transaction.
+ * @param cseq_method [in] CSeq method of failed transaction.
+ */
+ void push_failure(t_failure f, const string &branch, const t_method &cseq_method);
+
+ /**
+ * Create a start timer event.
+ * @param t [in] Timer to start.
+ */
+ void push_start_timer(t_timer *t);
+
+ /**
+ * Create a stop timer event.
+ * @param timer_id [in] Timer id of timer to stop.
+ */
+ void push_stop_timer(unsigned short timer_id);
+
+ /**
+ * Create an abort transaction event.
+ * @param tid [in] Transaction id of transaction to abort.
+ */
+ void push_abort_trans(unsigned short tid);
+
+ /**
+ * Create a STUN request event.
+ * @param user_config [in] The user profile associated with the request.
+ * @param m [in] STUN request.
+ * @param ev_type [in] Type of STUN event.
+ * @param tuid [in] Transaction user id.
+ * @param tid [in] Transaction id.
+ * @param ipaddr [in] Destination address (host order)
+ * @param port [in] Destination port (host order)
+ * @param src_port [in] Source port of media. This must only be passed for
+ * a media STUN event.
+ */
+ void push_stun_request(t_user *user_config, StunMessage *m, t_stun_event_type ev_type,
+ unsigned short tuid, unsigned short tid,
+ unsigned long ipaddr, unsigned short port, unsigned short src_port = 0);
+
+ /**
+ * Create a STUN response event.
+ * @param m [in] STUN response.
+ * @param tuid [in] Transaction user id.
+ * @param tid [in] Transaction id.
+ */
+ void push_stun_response(StunMessage *m,
+ unsigned short tuid, unsigned short tid);
+
+ /**
+ * Create a NAT keepalive event.
+ * @param ipaddr [in] Destination address (host order)
+ * @param port [in] Destination port (host order)
+ */
+ void push_nat_keepalive(unsigned long ipaddr, unsigned short port);
+
+ /**
+ * Create ICMP event.
+ * @param m [in] ICMP message.
+ */
+ void push_icmp(const t_icmp_msg &m);
+
+ /**
+ * Create a REFER pemission response event.
+ * @param permission [in] Permission allowed?.
+ */
+ void push_refer_permission_response(bool permission);
+
+ /**
+ * Create a broken connection event.
+ * @param user_uri [in] The user URI (AoR) associated with the connection.
+ */
+ void push_broken_connection(const t_url &user_uri);
+
+ /**
+ * Create a TCP ping event.
+ * @param user_uri [in] The user URI (AoR) for which the TCP ping must be sent.
+ * @param dst_addr [in] The destination IPv4 address for the ping.
+ * @param dst_port [in] The destination TCP port for the ping.
+ */
+ void push_tcp_ping(const t_url &user_uri, unsigned int dst_addr, unsigned short dst_port);
+
+ /**
+ * Pop an event from the queue.
+ * If the queue is empty then the thread will be blocked until an
+ * event arrives.
+ * @return The popped event.
+ */
+ t_event *pop(void);
+
+ /**
+ * Pop an event from the queue.
+ * Same method as above, but this one can be interrupted by
+ * calling the method interrupt.
+ * @param interrupted [out] When the pop operation is interrupted this
+ * parameter is set to true. Otherwise it is false.
+ * @return NULL, when interrupted.
+ * @return The popped event, otherwise.
+ */
+ t_event *pop(bool &interrupted);
+
+ /**
+ * Send an interrupt.
+ * This will cause the interruptable pop to return.
+ * A non-interruptable pop will ignore the interrupt.
+ * If pop is currently not suspending the thread execution then the
+ * next call to pop will catch the interrupt.
+ */
+ void interrupt(void);
+};
+
+#endif