Libevent 官方文檔學習筆記(3. evbuffer部分)

本文地址:http://www.javashuo.com/article/p-npzxkeen-es.htmlsegmentfault

 Evbuffers: 緩衝化的I/O實用工具 


頭文件:<event2/buffer.h>數組

Evbuffer基本操做

struct evbuffer *evbuffer_new (void);
void evbuffer_free (struct evbuffer *buf);

建立/銷燬evbuffer服務器

int evbuffer_enable_locking (struct evbuffer *buf, void *lock);
void evbuffer_lock (struct evbuffer *buf);
void evbuffer_unlock (struct evbuffer *buf);

第一個函數,參數locking傳入的參數是一個鎖。能夠傳入NULL,讓evbffer自動建立一個鎖。網絡

size_t evbuffer_get_length (const struct evbuffer *buf);
size_t evbuffer_get_continous_space (const struct evbuffer *buf);

第一個函數,獲取當前evbuffer的總數據長度。第二個函數,因爲數據在evbuffer的內存中並非連續保存的,這裏返回第一個chunk的大小。多線程

操做evbuffer中的幀

int evbuffer_add (struct evbuffer *buf, const void *data, size_t data_len);
int evbuffer_add_printf (struct evbuffer *buf, const char *fmt);
int evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap);

直接往evbuffer的末尾添加數據socket


int evbuffer_expand (struct evbuffer *buf, size_t data_len);

擴展ev_buffer的預申請內存函數


int evbuffer_add_buffer (struct evbuffer *dst, struct evbuffer *src);
int evbuffer_rename_buffer (struct evubffer *src, struct evbuffer *dst, size_t data_len);

兩個函數都是「move」操做,也就是說會刪除src的指定內容。工具


int evbuffer_prepend (struct evbuffer *buf, const void *data, size_t size);
int evbuffer_prepend_buffer (struct evbuffer *dst, struct evbuffer *src);

這兩個函數是往evbuffer的頭部插入數據oop


unsigned char *evbuffer_pullup (struct evbuffer *buf, ev_ssize_t size);

將指定長度的數據存入到evbuffer的第一個chunk中。若是size爲-1,則表示所有。學習


int evbuffer_drain (struct evbuffer *buf, size_t len);
int evbuffer_remove (struct evbuffer *buf, void *data, size_t data_len);

從evbuffer的頭部放走指定長度的數據,第二個函數能夠順帶讀出來。

基於字符串行的輸入

不少文件都是一行一行存儲的(好比文本),一下函數能夠用來一行一行地讀取輸入(ASCII)。讀取以前要指定行尾的格式。

enum evbuffer_eol_style {
    EVBUFFER_EOL_ANY,            // 任意數量的\r和\n
    EVBUFFER_EOL_CRLF,           // \r或者\r\n
    EVBUFFER_EOL_CRLF_STRICT,    // \r\n
    EVBUFFER_EOL_LF,             // \n
    EVBUFFER_EOL_NUL             // \0
};
char *evbuffer_readln (struct evbuffer *buffer,
                       size_t *n_read_out,
                       enum evbuffer_eol_style eol_style);

在evbuffer裏面搜索

Evbuffer使用一個結構體來配置搜索功能,其中pos表示position,以下:

struct evbuffer_ptr {
    ev_ssize_t pos;
    struct {/* internal fields */} _internal;
};
struct evbuffer_ptr evbuffer_search (struct evbuffer *buffer,
                                     const char *what,
                                     size_t len,
                                     const struct evbuffer_ptr *start);
struct evbuffer_ptr evbuffer_search_range (struct evbuffer *buffer,
                                           const char *what,
                                           size_t len,
                                           const struct evbuffer_ptr *start,
                                           const struct evbuffer_ptr *end);
struct evbuffer_ptr evbuffer_search_eol (struct evbuffer_ptr *buffer,
                                         struct evbuffer_ptr *start,
                                         size_t *eol_len_out,
                                         enum evbuffer_eol_style eol_style);

第一個參數是搜索在evbuffer中與「what」參數相同的數據而且返回。若是參數start不爲空,則會從start中所指定的位置開始搜索。
  第二個函數的不一樣是指定了一個搜索範圍;第三個函數相似於evbuffer_readln,可是不復制,只是返回結果而已。


enum evbuffer_ptr_how {
    EVBUFFER_PTR_SET,
    EVBUFFER_PTR_ADD,
};
int evbuffer_ptr_set (struct evbuffer *buffer,
                      struct evbuffer_ptr *pos,
                      size_t position,
                      enum evbuffer_ptr_how how);

修改evbuffer中的evbuffer_ptr。

檢查數據可是不復製出來

sruct aevbuffer_iovec {
    void *iov_base;
    size_t iov_len;
};
int evbuffer_peak (struct evbuffer *buffer,
                   ev_size_t len,
                   struct evbuffer_ptr *start_atm
                   struct evbuffer_iovec *vec_out,
                   int n_vec);

這個函數給予一個struct evbuffer_iovec數組,而且用n_vec制定長度,從evbuffer中獲得的具體數據塊的信息,這樣就能夠直接讀取了。
若是start_at非空,則直接從制定的位置讀起。

直接向evbuffer添加數據

int evbuffer_reserve_space (struct evbuffer *buf,
                            ev_size_t size,
                            struct evbuffer_iovec *vec,
                            int n_vecs);
int evbuffer_commit_space (struct evbuffer *buf,
                           struct evbuffer_iovec *vec,
                           int n_vecs);

這個函數與peak相似,不一樣的是使用這個組合,能夠直接修改evbuffer裏面的值。
若是是多線程的狀況下,注意要在reserve以前加鎖、commit以後解鎖。

使用evbuffer對網絡I/O進行讀寫

int evbuffer_write (struct evbuffer *buffer, evutil_socket_t fd);
int evbuffer_write_almost (struct evbuffer *buffer, evutil_socket_t fd, ev_ssize_t howmuch);
int evubffer_read (struct evbuffer *buffer, evutil_socket_t fd, ev_ssize_t howmuch);

evbuffer_write等同於evbuffer_write_almost中的howmuch參數指定爲-1。

Evbuffer的回調函數

struct evbuffer_cb_info {
    size_t orig_size;
    size_t n_added;
    size_t n_deleted;
};
typedef void (*evbuffer_cb_func)(struct evbuffer *buffer,
                                 const struct evbuffer_cb_info *info,
                                 void *arg);
                                 
struct evbuffer_cb_func;
struct evbuffer_cb_func *evbuffer_add_cb (struct evbuffer *buffer,
                                           evbuffer_cb_func cb,
                                           void *cbarg);

evbuffer有操做時,會調用callback,返回entry,則能夠用來在後續的函數中引用這個callback。

int evbuffer_remove_cb_entry (struct evbuffer *buffer, struct evbuffer_cb_func *ent);
int evbuffer_remove_cb (struct evbuffer *buffer, evbuffer_cb_func cb, void *cbarg);

這兩個函數用於刪除callback

int evbuffer_defer_callbacks (struct evbuffer *buffer, struct event_base *base);

Evbuffer的callback也能夠放在event loop裏面,這兩個函數就是將callback進行defer的函數

爲基於evbuffer的I/O減小數據複製

基於evbuffer常常會有數據複製,可是不少大負荷的服務器要儘可能減小這些操做,此時就須要如下函數:

typedef void (*evbuffer_ref_cleanup_cb) (const void *data, size_t datalen, void *extra);
int evbuffer_add_reference (struct evbuffer *outbuf, 
                            const void *data, 
                            size_t datalen, 
                            evbufferref_cleanup_cb cleanupfn, 
                            void *extra);

這個函數經過引用想evbuffer添加一段void *數據而且指定其長度。這段數據必須持續保持有效,直到evbuffer調用callback爲止。

向evbuffer直接添加文件內容

(不多用,暫略)

evbuffer之間的複製

int evbuffer_add_buffer_reference (struct evbuffer *outbuf, struct evbuffer *inbuf);

暫時凍結evbuffer

int evbuffer_freeze (struct evbuffer *buf, int at_front);
int evbuffer_unfreeze (struct evbuffer *buf, int at_front);

系列篇

Libevent官方文檔學習筆記(1. libevent_core部分)
Libevent官方文檔學習筆記(2. bufferevent部分)
Libevent官方文檔學習筆記(3. evbuffer部分)(本文)

相關文章
相關標籤/搜索