2 * PgBouncer - Lightweight connection pooler for PostgreSQL.
4 * Copyright (c) 2007-2009 Marko Kreen, Skype Technologies OÜ
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * event types for protocol handler
23 SBUF_EV_READ
, /* got new packet */
24 SBUF_EV_RECV_FAILED
, /* error */
25 SBUF_EV_SEND_FAILED
, /* error */
26 SBUF_EV_CONNECT_FAILED
, /* error */
27 SBUF_EV_CONNECT_OK
, /* got connection */
28 SBUF_EV_FLUSH
, /* data is sent, buffer empty */
29 SBUF_EV_PKT_CALLBACK
, /* next part of pkt data */
33 * If less that this amount of data is pending, then
34 * prefer to merge it with next recv().
36 * It needs to be larger than data handler wants
37 * to see completely. Generally just header,
38 * but currently also ServerParam pkt.
40 #define SBUF_SMALL_PKT 64
43 typedef struct SBuf SBuf
;
45 /* callback should return true if it used one of sbuf_prepare_* on sbuf,
46 false if it used sbuf_pause(), sbuf_close() or simply wants to wait for
47 next event loop (eg. too few data available). */
48 typedef bool (*sbuf_cb_t
)(SBuf
*sbuf
,
52 /* for some reason, libevent has no typedef for callback */
53 typedef void (*sbuf_libevent_cb
)(int, short, void *);
58 * Stream is divided to packets. On each packet start
59 * protocol handler is called that decides what to do.
62 struct event ev
; /* libevent handle */
64 bool is_unix
; /* is it unix socket */
65 uint8_t wait_type
; /* track wait state */
66 uint8_t pkt_action
; /* method for handling current pkt */
68 int sock
; /* fd for this socket */
70 unsigned pkt_remain
; /* total packet length remaining */
72 sbuf_cb_t proto_cb
; /* protocol callback */
74 SBuf
*dst
; /* target SBuf for current packet */
76 IOBuf
*io
; /* data buffer, lazily allocated */
79 #define sbuf_socket(sbuf) ((sbuf)->sock)
81 void sbuf_init(SBuf
*sbuf
, sbuf_cb_t proto_fn
);
82 bool sbuf_accept(SBuf
*sbuf
, int read_sock
, bool is_unix
) _MUSTCHECK
;
83 bool sbuf_connect(SBuf
*sbuf
, const PgAddr
*addr
, const char *unix_dir
, int timeout_sec
) _MUSTCHECK
;
85 bool sbuf_pause(SBuf
*sbuf
) _MUSTCHECK
;
86 void sbuf_continue(SBuf
*sbuf
);
87 bool sbuf_close(SBuf
*sbuf
) _MUSTCHECK
;
89 /* proto_fn can use those functions to order behaviour */
90 void sbuf_prepare_send(SBuf
*sbuf
, SBuf
*dst
, unsigned amount
);
91 void sbuf_prepare_skip(SBuf
*sbuf
, unsigned amount
);
92 void sbuf_prepare_fetch(SBuf
*sbuf
, unsigned amount
);
94 bool sbuf_answer(SBuf
*sbuf
, const void *buf
, unsigned len
) _MUSTCHECK
;
96 bool sbuf_continue_with_callback(SBuf
*sbuf
, sbuf_libevent_cb cb
) _MUSTCHECK
;
99 * Returns true if SBuf is has no data buffered
100 * and is not in a middle of a packet.
102 static inline bool sbuf_is_empty(SBuf
*sbuf
)
104 return iobuf_empty(sbuf
->io
) && sbuf
->pkt_remain
== 0;
107 static inline bool sbuf_is_closed(SBuf
*sbuf
)
109 return sbuf
->sock
== 0;