久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

参考资料学习APR库

發布時間:2024/1/23 编程问答 71 豆豆
生活随笔 收集整理的這篇文章主要介紹了 参考资料学习APR库 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

APR分析-整體篇

? ? 一、何為APR?

? ? ? ? ?Apache Server經過這么多年的發展后,將一些通用的運行時接口封裝起來供給大家,這就是Apache Portable Run-time libraries,APR。

? ? 二、APR的目錄組織

? ? ? ? ? 1)所有的頭文件都放在$(APR)/include目錄中;

? ? ? ? ? 2)所有功能接口的實現都放在各自的獨立目錄下,如threadproc、mmap等;

? ? ? ? ? 3)此外就是相關平臺構建工具文件如Makefile.in等。曾經看過ACE的代碼,ACE的所有源文件(.cpp)都放在一個目錄下,顯得很混亂。

? ? ? ? ? ?4)進入各功能接口子目錄,以threadproc為例,在其下面的子目錄有5個,分別是beos、netware、os2、unix和win32.

? ? 三、APR構建

? ? ? ? ? ?如果想要使用APR,需要先在特定平臺上構建它,這里不考慮多個平臺的特性,僅針對Unix平臺進行分析。

? ? ? ? ? ?1) apr.h、apr.h.in、apr.h.hw和apr.h.hnw的關系

? ? ? ? ? ? ? ?在$(APR)/include目錄下,由于APR考慮移植性等原因,最基本的apr.h文件是在構建時自動生成的,其中apr.h.in類似一模板作為apr.h生成程序的輸入源。其中apr.h.hw和apr.h.hnw分別是Windows和NetWare的特定版本。

? ? ? ? ? ?2) 編譯時注意事項

? ? ? ? ? ? ? ? 在Unix上編譯時,注意$(APR)/build下*.sh文件的訪問權限,應該先chmod以下,否則Make的時候會提示ERROR。

? ? 四、應用APR

? ? ? ? ? ? 我們首先make install一下,比如我們在Makefile中指定prefix=$(APR)/dist,則make install后,在$(APR)/dist下會發現4個子目錄,分別為bin、lib、include和build,其中我們感興趣的只有include和lib。

? ? ? ? ? ? ?下面是一個APR app的例子project。

? ? ? ? ? ? ?該工程的目錄組織如下:

$(apr_path)- dist- lib- include- examples- apr_app- Make.properties- Makefile- apr_app.c

? ? ? ? ? ? ? 我們的Make.properties文件內容如下:

# # The APR app demo # CC = gcc -Wall BASEDIR =$(HOME)/apr-1.1.1/examples/apr_app APRDIR =$(HOME)/apr-1.1.1 APRVER = 1 APRINCL =$(APRDIR)/dist/include/apr-$(APRVER) APRLIB =$(APRDIR)/dist/lib DEFS = -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -D_DEBUG_ LIBS = -L$(APRLIB) -lapr-$(APRVER) /-lpthread -lxnet -lposix4 -ldl -lkstat -lnsl -lkvm -lz -lelf -lm -lsocket -ladmINCL = -I$(APRINCL) CFLAGS =$(DEFS) $(INCL)Makefile文件內容如下: include Make.properties TARGET = apr_app OBJS = apr_app.o all: $(TARGET) $(TARGET): $(OBJS)$(CC) ${CFLAGS} -o $@$(OBJS) ${LIBS} clean:rm -f core $(TARGET)$(OBJS)

? ? ?而apr_app.c文件采用的是$(par_path)/test目錄下的proc_child.c文件。

五、GO ON

? ? 5.1 APR分析-設計篇

? ? ? ? 5.1.1 類型

? ? ? ? ? ? ?1) APR提供的節本自定義數據類型包括:

typedef unsigned char apr_byte_t; typedef short apr_int16_t; typedef unsigned short apr_uint16_t; typedef int apr_int32_t; typedef unsigned int apr_uint32_t; typedef long long apr_uint32_t; typedef long long apr_int64_t; typedef unsigned long long apr_uint64_t;

? ? ? ? ? ? ?這些都是在apr.h中定義的。

? ? ? ? ? ? ?2)在APR的設計文檔中,它稱"dso、mmap、process、thread"等為"base types"。

? ? ? ? ? ? ?3) 另外的一個特點就是大多APR類型中都包含一個apr_pool_t類型的字段,你最好在該類型中假如一個apr_pool_t類型的字段,否則所有操作該類型的APR函數都需要一個apr_pool_t類型的參數。

? ? ? ?5.1.2 函數

? ? ? ? ? ? 1) APR的固定個數參數公共函數的聲明形式APR_DECLARE(rettype) apr_func(args);而非固定個數參數的公共函數的聲明形式為APR_DECLARE_NONSTD(rettype) apr_func(args,...);".在Unix上的apr.h中有著兩個宏的定義:

#define APR_DECLARE(type) type #define APR_DECLARE_NONSTD(type) type

? ? ? ? ? ? ? ? ? 在apr.h文件中解釋了這么做就是為了在不同平臺上編譯時使用“the most appropriate calling convention”,這里的"calling convention"是一術語,叫"調用約定".常見的調用約定有:stdcall、cdecl、fastcall、thiscall和naked call,其中cdecl調用約定又稱為C調用約定,是C語言缺省的調用約定。

? ? ? ? ? ? ?2)如果你想新增APR函數,APR建議你最好按照如下做:

? ? ? ? ? ? ? ? ?a)輸出參數為第一個參數:

? ? ? ? ? ? ? ? ? b)如果某個函數需要內部分配內存,則將一個apr_pool_t 參數放在最后。

? ? ? ? ? 5.1.3 錯誤處理

? ? ? ? ? ? ? ? APR作為一通用的庫接口集合詳細的說明了使用APR時如何進行錯誤處理。

? ? ? ? ? ? ? ?1) 錯誤處理的第一步就是"錯誤碼和狀態碼分類"。APR的函數大部分都返回apr_status_t類型的錯誤碼,這是一個int型,在apr_errno.h中定義,和它在一起定義的還有apr所用的所有錯誤碼和狀態碼。

? ? ? ? ? ? ? ? 2) 如何定義錯誤捕捉策略?

? ? ? ? ? ? ? ? ? ?由于APR是可移植的,這樣就可能遇到這樣一個問題:不同平臺錯誤碼的不一致。如何處理呢?APR給我們提供了2中策略:

? ? ? ? ? ? ? ? ? ? ?a) 跨多平臺返回相同的錯誤碼

? ? ? ? ? ? ? ? ? ? ?b)返回平臺相關錯誤碼,如果需要將它轉換為通用錯誤碼

? ? ? ? ? ? ? ? ? ? ? ? ?程序的執行錄像往往要根據函數返回錯誤碼來定,這么做的缺點就是把這些工作推給了程序員。執行流程如下:

? ? ? ? ? ? ? ? ? ? ? ? ?make syscall that fails

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return error code

? ? ? ? ? ? ? ? ? ? ? ?----------------------------------------------------------------

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? convert to common error code (using ap_canonical_error)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? decide execution based on common error code

? ? ? ? ? ? ? ? ? ? ///

? ? ? ? ? ? ? ? ? ? 注1 調用約定

? ? ? ? ? ? ? ? ? ? ? ? ? ?我們知道函數調用是通過棧操作來完成的,在棧操作過程中需要函數的調用者和被調用者在下面的兩個問題上作出協調,達成協議:

? ? ? ? ? ? ? ? ? ? ? ? ? ?a) 當參數個數多余一個時,按照什么順序把參數壓入堆棧

? ? ? ? ? ? ? ? ? ? ? ? ? ?b) 函數調用后,由誰來把堆?;貜驮瓉頎顟B

? ? ? ? ? ? ? ? ? ? ? ? ? ?在像C/C++這樣的中、高級語言中,使用"調用約定"來說明這兩個問題。

? ? ? ? ? ? ? ? ? ?///

? ?5.2 APR分析-進程篇

? ? ? ? ?Apache Server的進程調度一直為人所稱道,Apache 2.0推出的APR對進程進行了封裝,特別是Apache 2.0的MPM(Multiple Precess Management)框架就是以APR封裝的進程為基礎的。

? ? ? ? ? ? ?APR進程封裝源代碼的位置在$(APR_HOME)/threadproc目錄下,本篇blog著重分析unix子目錄下的proc.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_thread_proc.h。

? ? ? ? ?一、APR進程概述

? ? ? ? ? ? ? APR進程封裝采用了傳統的fork-exec配合方式(spawn),即父進程在fork出子進程后繼續執行其自己的代碼,而子進程調用exec函數加載新的程序影響到其地址空間,執行新的程序。我們先來看看使用APR創建一個新的進程的流程,然后再根據流程做細節分析:

apr_proc_t newproc; apr_pool_t *p; apr_status_t rv; const char *args[2]; apr_procattr_t *attr; /* 初始化APR內部使用的內存*/ rv = apr_pool_initialize(); HANDLE_RTVAL(apr_pool_initialize, rv); rv = apr_pool_create(&p, NULL); HANDLE_RTVAL(apr_pool_create, rv); /*創建并初始化新進程的屬性*/ rv = apr_procattr_create(&attr, p); HANDLE_RTVAL(apr_procattr_create, rv); rv = apr_procattr_io_set(attr, APR_FULL_BLOCK, APR_FULL_BLOCK, APR_NO_PIPE); /*可選*/ HANDLE_RTVAL(apr_procattr_io_set, rv); rv = apr_procattr_dir_set(attr, "startup_path");/*可選*/ HANDLE_RTVAL(apr_procattr_dir_set, rv); rv = apr_procattr_cmdtype_set(attr, APR_PROGRAM);/*可選*/ HANDLE_RTVAL(apr_procattr_cmdtype_set, rv); ... .../*其他設置進程屬性的函數*/ /*創建新進程*/ args[0] = "proc_child"; args[1] = NULL; rv = apr_proc_create(&newproc,"your_progname", args, NULL, attr, p); HANDLE_RTVAL(apr_proc_create, rv); /*等待子進程結束*/ rv = apr_proc_wait(&newproc, NULL, NULL, APR_WAIT); HANDLE_RTVAL(apr_proc_wait, rv);

? ? ? ? ? ?二、APR procattr創建

? ? ? ? ? ? ? ? ?在我們平時的Unix進程相關編程時,我們大致會接觸兩類進程操作函數:進程創建函數(如fork和exec等)和進程屬性操作函數(getpid、chdir等),APR將進程的相關屬性信息封裝到apr_procattr_t結構體中,我們來看看這個重要的結構體定義:(這里只列出Unix下可用的屬性)

/* in $(APR_HOME)/include/arch/unix/apr_arch_threadproc.h */ struct apr_procattr_t {/* PART 1 */apr_pool_t *pool;/* PART 2 */apr_file_t *parent_in;apr_file_t *child_in;apr_file_t *parent_out;apr_file_t *child_out;apr_file_t *parent_err;apr_file_t *child_err;/* PART 3 */char *currdir;apr_int32_t cmdtype;apr_int32_t detached;/* PART 4 */struct rlimit *limit_cpu;struct rlimit *limit_mem;struct rlimit *limit_nproc;struct rlimit *limit_nofile;/* PART 5 */apr_child_errfn_t *errfn;apr_int32_t errchk;/* PART 6 */apr_uid_t uid;apr_gid_t gid; };

? ? ? ?我這里講apr_procattr_t 包含的字段大致分為6部分,下面逐一說明:

? ? ? ? [PART 1]

? ? ? ? 在上一篇關于APR的blog中說過,大部分的APR類型中都會有一個apr_pool_t 類型字段,用于APR內部的內存管理,此結構也無例外。該字段用來標識procattr在哪個pool中分配的內存。

? ? ? ? [PART 2]

? ? ? ? 進程不是孤立存在的,進程也是由父有子的。父子進程間通過傳統的匿名pipe進行通信。在apr_procattr_io_set(attr,APR_FULL_BLOCK,APR_FULL_BLOCK,APR_FULL_BLOCK)調用后,我們可以用下面的圖來表示這些字段的狀態:

parent_in----------------------------------------------------------filedes[0] "in_pipe" filedes[1]------------------------ chiild_in ----- parent_out---------------------------filedes[0] "out_pipe" filedes[1]------------------------ child_out ---------------------- parent_err ---------------------------filedes[0] "err_pipe" filedes[1]------------------------ child_err ---------------------------

? ? ? ? 還有一點指的注意的是apr_procattr_io_set調用apr_file_pipe_create創建pipe的時候,為相應的in/out字段注冊了cleanup函數apr_unix_file_cleanup, apr_unix_file_cleanup在相應的in/out字段的pool銷毀時被調用,在后面的apr_proc_create時還會涉及到這塊。

? ? ? ? [PART 3]

? ? ? ? 進程的一些常規屬性。

? ? ? ? currdir標識新進程啟動時的工作路徑(執行路徑),默認時為何父進程相同;

? ? ? ? cmdtype標識新的子進程將執行什么類型的命令;共5種類型,默認為APR_PROGRAM

? ? ? ? detached標識新進程是否為分離后臺進程,默認為前臺進程。

? ? ? ? [PART 4]

? ? ? ? 這4個字段標識平臺對進程資源的限制,一般我們接觸不到。struct rlimit的定義在/usr/include/sys/resource.h中。

? ? ? ? [PART 5]?

? ? ? ? errfn為一函數指針,原型為typedef void (apr_child_errfn_t)(apr_pool_t *proc, apr_status_t err, const char *description);這個函數指針如果被賦值,那么當子進程遇到錯誤退出前將調用該函數。

? ? ? ? ? ? errchk一個標志值,用于告知apr_proc_create是否對子進程屬性進行檢查,如檢查curdir的access屬性等。

? ? ? ? [PART 6]

? ? ? ? ? ? 用戶ID和組ID,用于檢索允許該用戶所使用的權限。

? ? ? ? 三、APR proc創建

? ? ? ? ? ? APR proc的描述結構為apr_proc_t:

typedef struct apr_proc_t {/** The process ID */pid_t pid;/** Parent's side of pipe to child's stdin */apr_file_t *in;/** Parent's side of pipe to child's stdout */apr_file_t *out;/** Parent's side of pipe to child's stderr*/apr_file_t *err; } apr_proc_t;

? ? ? ? ? ? 創建一個新的進程的接口為apr_proc_create,其參數也都很簡單。前面說過apr_proc_create先fork出一個子進程,眾所周知fork后子進程是父進程的復制品,然后子進程再通過exec函數加載新的程序映像,并開始執行新的程序。這里分析一下apr_proc_create的執行流程,其偽碼如下:

apr_proc_create {if (attr->errchk)對attr做有效性檢查,讓錯誤盡量發生在parentprocess中,而不是留給child process; ---(1)fork子進程;{ /*在子進程中*/清理一些不必要的從父進程繼承下來的描述符等,為exec提供一個"干凈的"的環境 ---(2)關閉attr->parent_int、parent_out和parent_err,并分別重定向attr->child_in、child_out和child_err為STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO; ---(3)判斷attr->cmdtype,選擇執行exec函數; --(4)}/* 在父進程中*/關閉attr->child_in、child_out和child_err; }

? ? ? ?下面針對上述偽碼進行具體分析:

? ? ? ? 1)有效性檢查

? ? ? ? ? ? attr->errchk屬性可以通過apr_procattr_error_check_set函數在apr_proc_create之前設置。一旦設置,apr_proc_create就會在fork子進程前對procattr的有效性進行檢查,比如attr->curdir的訪問屬性(利用access檢查)、progname文件的訪問權限檢查等。這些的目的就是一個"讓錯誤發生在fork前,不要等到在子進程中出錯"。

? ? ? ? 2) 清理"不必要的"繼承物

? ? ? ? ? ? ? ? ? ?由于子進程復制了父進程的地址空間,隨之而來的還包含一些"不必要"的"垃圾"。為了給exec提供一個"干凈的"環境,在exec之前首先要做一下必要的清理,APR使用apr_pool_cleanup_for_exec來完成這項任務。apr_pool_cleanup_for_exec做了哪些工作呢?apr_pool_cleanup_for_exec通過pool內部的global_pool搜索其子節點,并逐一遞歸cleanup,這里的cleanup并不釋放任何內存,也不flushI/O Buffer,僅是調用節點注冊的相關cleanup函數,這里我們可以回顧一下apr_procattr_io_set調用,在創建相關pipe時就為相應的in/out/err描述符注冊了cleanup函數。同樣就是因為這點,子進程再調用apr_pool_cleanup_for_exec之前,首先要kill掉(這里理解就是去掉相關文件描述符上的cleanup注冊函數)這些注冊函數。防止相關pipe的描述符被意外關閉。

? ? ? ? 3) 建立起與父進程"對話通道"

? ? ? ? ? ?父進程在創建procattr時就建立了若干個pipe,fork后子進程繼承了這些。為了關掉一些不必要的描述符和更好的和父進程通訊,子進程作了一些重定向的工作,這里用圖來表示重定向前后的差別:(圖中顯示的是子進程關閉parent_in/out/err三個描述符后的文件描述符表)

? ? ? ? ? ? 重定向前:

? ? ? ? ? ? ? ?子進程文件描述符

? ? ? ? ? ? ? ? ? ?----------------------------|

? ? ? ? ? ? ? ? ? ?[0] STDIN_FILENO|

? ? ? ? ? ? ? ? ? ?-----------------------------|

? ? ? ? ? ? ? ? ? ?[1] STDOUT_FILENO

? ? ? ? ? ? ? ? ? ?-----------------------------|

? ? ? ? ? ? ? ? ? ?[2] STDERR_FILENO

? ? ? ? ? ? ? ? ? ?------------------------------|

? ? ? ? ? ? ? ? ? ?[3] child_in.fd |----> in_pipe的filedes[0]

? ? ? ? ? ? ? ? ? ?-------------------------|

? ? ? ? ? ? ? ? ? ?[4] child_out.fd|--->out_pipe的filedes[1]

? ? ? ? ? ? ? ? ? ?-------------------------|

? ? ? ? ? ? ? ? ? ?[5] child_err.fd|--->err_pipe的filedes[1]

? ? ? ? ? ? ? ? ? ?----------------------|

? ? ? ? ? ? ? ? ? ?重定向后:

? ? ? ? ? ? ? ? ? ?-----------|

? ? ? ? ? ? ? ? ? ?[0] child_in.fd |--->in_pipe的filedes[0]

? ? ? ? ? ? ? ? ? ?-----------|

? ? ? ? ? ? ? ? ? ?[1]child_out.fd |--->out_pipe的filedes[1]

? ? ? ? ? ? ? ? ? ?-----------|

? ? ? ? ? ? ? ? ? ?[2]child_err.fd |---->err_pipe的filedes[1]

? ? ? ? ? ? ? ? ? ? -----------|

? ? ? ? ? ? ? ? ? ?為了能更好的體現出"對話通道"的概念,這里再畫出父進程再關閉attr->child_in、child_out和child_err后的文件描述表:

? ? ? ? ? ? ? ? ? ? ?父進程文件描述表

? ? ? ? ? ? ? ? ? ? ?-----------------|

? ? ? ? ? ? ? ? ? ? ?[0] STDIN_FILENO |

? ? ? ? ? ? ? ? ? ? ?-----------------|

? ? ? ? ? ? ? ? ? ? ?[1] STDOUT_FILENO |

? ? ? ? ? ? ? ? ? ? ?------------------|

? ? ? ? ? ? ? ? ? ? ?[2] STDERR_FILENO |

? ? ? ? ? ? ? ? ? ? ? ------------------|

? ? ? ? ? ? ? ? ? ? ? [3]parent_in.fd | ---->in_pipe的filedes[1]

? ? ? ? ? ? ? ? ? ? ? -------------------|

? ? ? ? ? ? ? ? ? ? ? [4] parent_out.fd |---->out_pipe的filedes[0]

? ? ? ? ? ? ? ? ? ? ? -------------------|

? ? ? ? ? ? ? ? ? ? ? [5] parent_err.fd |---->err_pipe的filedes[0]

? ? ? ? ? ? ? ? ? ? ? -------------------|

? ? ? ? 4) 啟動新的程序

? ? ? ? ? ? 根據APR proc的設計,子進程在被fork出來后,將根據procattr的cmdtype等屬性信息決定調用哪種exec函數。當子進程調用一種exec函數時,子進程將完全由新程序代換,而新程序則從其main函數開始執行(與fork不同,fork返回后子進程從fork點開始往下執行)。因為調用exec并不創建新進程,所以前后的進程ID并未改變。exec只是用另一個新程序替換了當前進程的正文、數據、堆和棧段。

? ? ? ? 四、總結

? ? ? ? ? ?xx_in/xx_out都是相對于child process來說的,xx_in表示通過該描述符child process從in_pipe讀出parent process寫入in_pipe的數據;xx_out表示通過該描述符child process將數據寫入out_pipe供parent process使用;xx_err則是child process將錯誤信息寫入err_pipe供parent process使用。

? ? ? ? ? ?fork后子進程和父進程的同和異

? ? ? ? ? ? ? 同:

? ? ? ? ? ? ? ?--父進程已經打開的文件描述符;

? ? ? ? ? ? ? ?--實際用戶ID、實際組ID、有效用戶ID、有效組ID;

? ? ? ? ? ? ? ?--添加組ID;

? ? ? ? ? ? ? ?--進程組ID;

? ? ? ? ? ? ? ?--對話期ID;

? ? ? ? ? ? ? ?--控制終端;

? ? ? ? ? ? ? ?--設置用戶ID標志和設置組ID標志;

? ? ? ? ? ? ? ?--當前工作目錄;

? ? ? ? ? ? ? ?--根目錄;

? ? ? ? ? ? ? ?--文件方式創建屏蔽字;

? ? ? ? ? ? ? ?--信號屏蔽和排列;

? ? ? ? ? ? ? ?--對任一打開文件描述符的在執行時關閉標志;

? ? ? ? ? ? ? ?--環境;

? ? ? ? ? ? ? ? --連接的共享存儲段;

? ? ? ? ? ? ? ? --資源限制.

? ? ? ? ? ? ? ?異:

? ? ? ? ? ? ? ? ?--fork的返回值;

? ? ? ? ? ? ? ? ?--進程ID;

? ? ? ? ? ? ? ? ? --不同的父進程ID;

? ? ? ? ? ? ? ? ?--子進程的tms_utime,tms_stime,tms_cutime以及tme_ustime設置為0;

? ? ? ? ? ? ? ? ?--父進程設置的鎖,子進程不繼承;

? ? ? ? ? ? ? ? ? --子進程的未決告警被清除;

? ? ? ? ? ? ? ? ? ?--子進程的未決信號集設置為空集

? 5.3 APR分析-內存篇

? ? ? ? 內存管理一直是讓C程序員頭痛的問題,作為一個通用接口集,APR當然也提供其自己的內存管理接口--APR Pool。APR Pool作為整個APR的一個基礎功能接口,直接影響著APR的設計風格。

? ? ? ? APR Pool源代碼的位置在$(APR_HOME)/memory目錄下,本篇blog著重分析unix子目錄下的apr_pools.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_pools.h;在apr_pools.c中還實現了負責APR內部內存分配的APRallocator的相關操作接口(APR allocator相關頭文件為$(APR_HOME)/include/apr_allocator.h)。

? ? ? ? 一、APR Pool概述

? ? ? ? ? ? ?我們平時常用的內存管理方式都是基于"request-style"的,即分配所請求大小的內存,使用之,銷毀之。而APR Pool的設計初衷是為Complex Application提供良好的內存管理接口,其使用方式與"request-style"有所不同。而$(APR_HOME)/docs/pool-design.htm文檔中,設計者道出了"使用好"APR Pool的幾個Rules,同時也從側面反映出APRPool的設計。

? ? ? ? ? ? ?1.任何Object都不應該有自己的Pool,它應在其構造函數的調用者的Pool中分配。因為一般調用者知道該Object的聲明周期,并通過Pool管理之。也就說Object無須自己調用"Close" or "Free",這些操作在Object所在Pool被摧毀時被隱式調用的。

? ? ? ? ? ? ? 2.函數無須為了他們的行為而去Create/Destroy Pool,它們應該使用它們調用者傳給它們的Pool。

? ? ? ? ? ? ? 3.為了防止內存無限制的增長,APR Pool建議當遇到unbounded iteration時使用sub_pool,標準格式如下:

subpool=apr_pool_create(pool,NULL); for(i=0;i<n;++i) {apr_pool_clear(subpool);... ...do_operation(..., subpool); } apr_pool_destroy(subpool);

? ? ? ? ? ?二、深入APR Pool

? ? ? ? ? ? ? ?1.分析apr_pool_initialize

? ? ? ? ? ? ? ? ? 任何使用APR的應用程序一般都會調用apr_app_initalize來初始化APR的內部使用的數據結構,查看一下app_app_initialize的代碼,你會發現apr_pool_initialize在被apr_app_initialize調用的apr_initialize中被調用,該函數用來初始化使用Pool所需的內部結構(用戶無須直接調用apr_pool_initialize,在apr_app_initialize時它被自動調用,而apr_app_initailize又是APR? program調用的第一個function,其在apr_general.h中聲明,在misc/unix/start.c中實現)。

? ? ? ? ? ? ? ? ?apr_pool_initialize {

? ? ? ? ? ? ? ? ? ? ? 如果(!apr_pools_initialized) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?創建global_allocator;? ?------(1)

? ? ? ? ? ? ? ? ? ? ? ?}


? ? ? ? ? ? ? ? ? ? ? ? 創建global_pool; ------(2)

? ? ? ? ? ? ? ? ? ? ? ? 給global_pool起名為"apr_global_pool";

? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? ? (1) Pool和Allocator

? ? ? ? ? ? ? ? ? ? ? ? ? ?每個Pool都有一個allocator相伴,這個allocator可能是Pool自己的,也可能是其ParentPool的。allocator的結構如下:

/* in apr_pools.c*/ struct apr_allocator_t {apr_uint32_t max_index;apr_uint32_t max_free_index;apr_uint32_t current_free_index;... ...apr_pool_t *owner;apr_memnode_t *free[MAX_INDEX]; }; ? ? ? ? ?在(1)調用后,global_allocator的所有xx_index字段都為0,owner-->NULL,free指針數組中的指針也都-->NULL。這里的index是大小的級別,這里最大級別為20(即MAX_INDEX=20),free指針數組中free[0]所指的node大小為MIN_ALLOC大小,即8192,即2的13次冪。按此類推free[19]所指的node大小應為2的32次冪,即4G byte。allocator_alloc中是通過index=(size >> BOUNDARY_INDEX) - 1來得到這一index的。allocator維護了一個index不同的memnode池,每一index級別上又有一個

memnode list,以后用戶調用apr_palloc分配size大小內存時,allocator_alloc函數就會在free memnode池中選和要尋找的size的index級別相同的memnode,而不是重新malloc一個size大小的memnode。另外要說明一點的是APR Pool中所有ADT中的xx_index字段都是大小級別的概念。

? ? ? ? ? ?(2) 創建global_pool

? ? ? ? ? ? ? 在APR Pool初始化的時候,唯一創建一個Pool --global_pool。apr_pool_t的非Debug版本如下:

/* in apr_pools.c */ struct apr_pool_t {apr_pool_t *parent;apr_pool_t *child;apr_pool_t *sibling;apr_pool_t **ref;cleanup_t *cleanups;cleanup_t *free_cleanups;apr_allocator_t *allocator;struct process_chain *subprocesses;apr_abortfunc_t abort_fn;apr_hash_t *user_data;const char *tag;apr_memnode_t *active;apr_memnode_t *self; /*The nodecontaining the pool itself */char *self_first_avail;... ... }

? ? ? ? ? ? ? 而apr_memnode_t的結構如下:

/* in apr_allocator.h */ struct apr_memnode_t {apr_memnode_t *next; /*next memnode */apr_memnode_t **ref; /*reference to self*/apr_uint32_t index; /*size*/apr_uint32_t free_index; /*how much free*/char *first_avail; /*pointer to first free memory*/char *endp; /*pointer to end of free memory */ };

? ? ? ? ? ? ? apr_pool_create_ex首先通過allocator尋找合適的node用于創建Pool,但由于global_allocator尚未分配過任何node,所以global_allocator創建一個新的node,該node大小為MIN_ALLOC(即8192),該node的當前狀態如下:

node-->|----------|0| || ||----------|APR_MEMNODE_T_SIZE <----node->first_avail| || || ||----------size(一般為8192)<---node->endp

? ? ? ? ? ? ?其他屬性值如下:

? ? ? ? ? ? ?node->next = NULL;

? ? ? ? ? ? ?node->index = (APR_UINT32_TRUNC_CAST)index; /*這里為1*/

? ? ? ? ? ? ?創建完node后,我們將在該node上的avail space劃分出我們的global_pool來。劃分后狀態如下(pool與node關系):

node-->|----------|0 <---pool->self=pool_active| || ||-------------|APR_MEMNODE_T_SIZE <------global_pool| || ||--------------|APR_MEMNODE_T_SIZE+SIZEOF_POOL_T <------node->first_avail=pool->self_first_avail| || ||------------size(一般為8192) <------------node->endp

? ? ? ? ? ? ?pool其他一些屬性值(pool與pool之間關系)如下:

pool->allocator=global_allocator; pool->child = NULL; pool->sibling = NULL; pool->ref = NULL;

? ? ? ? ? ? ? ? ?2.APR Sub_Pool創建(pool與pool之間關系)

? ? ? ? ? ? ? ? ? 上面我們已經初始化了global_pool,但是global_pool是不能直接拿來就用的,我們需要創建其sub_pool,也就是用戶自己的pool。一般創建user的sub_pool我們都使用apr_pool_create宏,它只需要2個參數,并默認sub_pool繼承parent_pool的allocator和abort_fn。在apr_pool_create內部調用的還是apr_pool_create_ex函數。我們來看一下創建sub_pool后pool之間的關系:

? ? ? ? ? ? ? ? ? 例:

? ? ? ? ? ? ? ? ? ?static apr_pool_t *sub_pool = NULL;

? ? ? ? ? ? ? ? ? ?apr_pool_create(&sub_pool, NULL);

? ? ? ? ? ? ? ? ? ?這里sub_pool的創建過程與global_pool相似,也是先創建其承載體node,然后設置相關屬性,使其成為global_pool的child_pool。創建完后global_pool和該sub_pool的關系如下圖:

global_pool <------/ ----->sub_pool ---------- // -------- sibling --->NULL /--------parent ---------- / -------- child--------------/ sibling--->NULL -------- ---------child--->NULL---------

? ? ? ? ? ? ? ? ?APR Pool是按照二叉樹結構組織的,并采用"child-sibling"的鏈式存儲方式,global_pool作為整個樹的Root Node。

? ? ? ? ? ? ? ? ?3.從pool中分配內存

? ? ? ? ? ? ? ? ? ? 上面我們已經擁有了一個sub_pool,我們現在就可以從sub_pool中分配內存了。APR提供了函數apr_palloc來做這件事情。

? ? ? ? ? ? ? ? ? ? ? 例如:apr_alloc(sub_pool,wanted_mem_size);

? ? ? ? ? ? ? ? ? ? ? ?apr_palloc在真正分配內存前會把wanted_mem_size做一下處理。它使用APR_ALIGN_DEFAULT宏處理wanted_mem_size得到一個圓整到8的new_size,然后再在pool中分配new_size大小的內存,也就是說pool中存在的用戶內存塊的大小都是8的倍數。舉個例子,如果wanted_mem_size=30,apr_alloc實際會在pool中劃分出32個字節的空間。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? apr_palloc的工作流程簡單描述如下:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?a) 如果在pool->active node的avail space足夠滿足要申請的內存大小size時,則直接返回active->first_avail,并調整active->first_avail= active->first_avail+size;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?b)如果a)不滿足,則查看active->next這個node滿足與否;如果滿足則將返回所要內存,并將該node設為active node,將以前的active node放在新active node的next位置上;

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c)如果b)也不滿足,則新創建一個memnode,這個node可能為新創建的,也可能是從allocator的free memnode池中取出的,取決于當時整個Pool的狀態。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 從上面我們也可以看出node分為2類,一種是作為pool的承載體,但pool結構的空間不足以完全占滿一個node,所以也可以用來分配用戶內存;另一種就是完全用于分配用戶內存的了。每個pool有一個node list,當然這個list中包括它自己所在的node了。

? ? ? ? ? ? ? ? ? 4.apr_pool_clear和apr_pool_destroy

? ? ? ? ? ? ? ? ? ? 創建和分配結束后,我們需要clear或者destroy掉Pool。

? ? ? ? ? ? ? ? ? ? clear和destroy的區別在于clear并不真正free內存,只是清理便于以后alloc時重用,而destroy則是真正的free掉內存了。

? 5.4 APR分析-信號篇

? ? ? ? ?信號是Unix的重要系統機制。

? ? ? ? ?一、信號介紹

? ? ? ? ? ? ? ?1.Signal的引入用來進行User Mode進程間的交互,系統內核也可以利用它通知User Mode進程發生了哪些系統事件。從最開始引入到現在,信號只是做了很小的一些改動(不可靠信號模型到可靠信號模型).

? ? ? ? ? ? ? ? ?2.信號服務于兩個目的:

? ? ? ? ? ? ? ? ? ?1) 通知某進程某特定事件發生了;

? ? ? ? ? ? ? ? ? ?2) 強制其通知進程執行相應的信號處理程序。

? ? ? ? ? 二、基礎概念

? ? ? ? ? ? ? ? ? 1.信號的一個特性就是可以在任何時候發給某一進程,而無需知道該進程的狀態。如果該進程當前并未處于執行態,則該信號被內核Save起來,知道該進程恢復執行才傳遞給它;如果一個信號被進程設置為阻塞,則該信號的傳遞被延遲,直到其阻塞被取消它才被傳遞給進程。

? ? ? ? ? ? ? ? ? ?2.系統內核嚴格區分信號傳送的兩個階段:

? ? ? ? ? ? ? ? ? ? ?1)Signal Generation: 系統內核更新目標進程描述結構來表示一個信號已經發送出去。

? ? ? ? ? ? ? ? ? ? ?2)Signal Delivery:內核強制目標進程對信號做出反應,或執行相關信號處理函數,或改變進程執行狀態。

? ? ? ? ? ? ? ? ? ? ?信號的誕生和傳輸我們可以這樣理解:把信號作為"消費品",其Generation狀態就是"消費品誕生",其Delivery狀態就是理解為"被消費了"。這樣勢必存在這樣的一個情況:"消費品誕生了,但是還沒有被消費掉",在信號模型中,這樣的狀態被稱為"pending"(懸而未決)。

? ? ? ? ? ? ? ? ? ? ? 任何時候一個進程只能有一個這樣的某類型的pending信號,同一進程的其他同類型的pending信號將不排隊,將被簡單的discard(丟棄)掉。

? ? ? ? ? ? ? ? ? ?3.如何消費一個signal

? ? ? ? ? ? ? ? ? ? ? 1) 忽略該信號;

? ? ? ? ? ? ? ? ? ? ? 2)響應該信號,執行一特定的信號處理函數;

? ? ? ? ? ? ? ? ? ? ? 3)響應該信號,執行系統默認的處理函數。包括:Terminate、Dump、Ignore、Stop、Continue等。

? ? ? ? ? ? ? ? ? ? ? 這里有特殊:SIGKILL和SIGSTOP兩個信號不能忽略、不能捕捉、不能阻塞,而只是執行系統默認處理函數。

? ? ? ? ? ?三、APR Signal封裝

? ? ? ? ? ? ? ? ?APR Signal源代碼的位置在$(APR_HOME)/threadproc目錄下,本篇blog著重分析unix子目錄下的signals.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_signal.h。

? ? ? ? ? ? ? ? ? ?1.apr_signal函數

? ? ? ? ? ? ? ? ? ? ? ?早期版本處理方式:進程每次處理信號后,隨機將信號的處理動作重置為默認值。

? ? ? ? ? ? ? ? ? ? ? ?后期版本處理方式:進程每次處理信號后,信號的處理動作不被重置為默認值。

? ? ? ? ? ? ? ? ? ? ? ?我們舉例測試一下:分別在Solaris9、Cygwin和RedHat Linux 9上。

? ? ? ? ? ? ? ? ? ? ? ?例子:

? ? ? ? ? ? ? ? ? ? ? ?eg 1:

void siguser1_handler(int sig); int main(void) {if (signal(SIGUSR1, siguser1_handler) == SIG_ERR) {perror("siguser1_handler error");exit(1);}while(1) {pause();} } void siguser1_handler(int sig) {printf("in siguser1_handler,%d/n", sig); } input:kill -USR1 9122kill -USR1 9122 output(Solaris 9):in siguser1_handler, 16用戶信號1(程序終止) output:(Cygwin and RH9):in siguser1_handler, 30in siguser1_handler, 30.....

? ? ? ? ? ? ? ? ? ? ? ? ? eg.1結果表示在Solaris 9上,信號的處理仍然按照早期版本的方式,而Cygwin和RH9則都按照后期版本的方式。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?那么有什么替代signal函數的辦法么?在最新的X/Open和UNIXspecifications中都推薦使用一個新的信號接口sigaction,該接口采用后期版本的信號處理方式。在《Unix高級環境編程》中就有使用sigaction實現signal的方法,而APR恰恰也是使用了該方法實現了apr_signal。其代碼如下:

APR_DECLARE(apr_sigfunc_t *) apr_signal(int signo, apr_sigfunc_t *func) {struct sigaction act, oact;act.sa_handler = func;sigemptyset(&act.sa_mask); ----(1)act.sa_flags=0; #ifdef SA_INTERRUPT /* SunOS */act.sa_flags |= SA_INTERRUPT; #endif... ...if (sigaction(signo, &act, &oact) <0) return SIG_ERR;return oact.sa_handler; }

? ? ? ? ? ? ? ? ? ? ? ? (1)這里有一個Signal Set(信號集)的概念,通過相關函數操作信號集以改變內核傳遞信號給進程時的行為。Unix用sigset_t結構來表示信號集。信號集總是和sigprocmask或sigaction一起使用。

? ? ? ? ? ? ? ? ? ? ?2、apr_signal_block和apr_signal_unblock

? ? ? ? ? ? ? ? ? ? ? ? ? 這兩個函數分別負責阻塞和取消阻塞內核傳遞某信號給目標進程。其主要利用的就是sigprocmask函數來實現的。每個進程都有其對應的信號屏蔽字,它讓目標進程能夠通知內核"哪些傳給我的信號該阻塞,哪些暢通無阻"。

? ? ? ? ? ? ? ? ? ? ? ? ? ?這里想舉例說明的是:如果多次調用SET_BLOCK的sigprocmask設置屏蔽字,結果是什么呢?

? ? ? ? ? ? ? ? ? ? ? ? ?eg.3

int main(void) {sigset_t newmask, oldmask, pendmask;/* 設置進程信號屏蔽字,阻塞SIGQUIT */sigemptyset(&newmask);sigaddset(&newmask, SIGQUIT);if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {perror("SIG_BLOCK error");}printf("1st towait 30 seconds/n");sleep(30);/*第一次查看當前的處于pend狀態的信號*/if(sigpending(&pendmask) <0) {perror("sigpending error");}if (sigismember(&pendmask, SIGQUIT)) {printf("SIGQUIT pending /n");} else {printf("SIGQUIT unpending/n");}if (sigismember(&pendmask, SIGUSR1)) {printf("SIGUSR1 pending/n");} else {printf("SIGUSR1 unpending/n");}/*重新設置屏蔽字,阻塞SIGUSR1*/sigemptyset(&newmask);sigaddset(&newmask, SIGUSR1);if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) {perror("SIG_BLOCK error");}printf("2nd to wait 30 seconds/n");sleep(30);/*再次查看當前的處于pend狀態的信號*/if (sigpending(&pendmask) < 0) {perror("sigpending error");}if (sigismember(&pendmask, SIGQUIT)) {printf("SIGQUIT pending/n");} else {printf("SIGQUIT unpending /n");}if (sigismember(&pendmask, SIGUSR1)) {printf("SIGUSR1 pending/n");} else {printf("SIGUSR1 unpending/n");}exit(0); }//output 1st to wait 30 seconds ^/ SIGQUIT pending SIGUSR1 unpending 2nd to wait 30 seconds --這之后發送kill -USR128821 SIGQUIT pending SIGUSR1 pending

? ? ? ? ? ? ? ? ? ? ? ?第一次輸出SIGUSR1 unpending是因為并未發送USR1信號,所以自然為unpending狀態;我想說的是第二次重新sigprocmask時我們僅加入了SIGUSR1,并未顯示假如SIGQUIT,之后查看pending信號中SIGQUIT仍然為pending狀態,這說明兩次SET_BLOCK的sigprocmask調用是"或"的關系,第二次SET_BLOCK的sigprocmask調用不會將第一次SET_BLOCK的sigprocmask調用設置的阻塞信號變成非阻塞的。

? 5.5 APR分析-文件IO篇

? ? ? ? ?文件I/O在Unix下占據著非常重要的地位。APR就是本著這個思想對Unix文件I/O進行了再一次的抽象封裝,以提供更為強大和友善的文件I/O接口。

? ? ? ? ? APR File I/O源代碼的位置在$(APR_HOME)/file_io目錄下,本篇blog著重分析unix子目錄下的相關.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_file_io.h和apr_file_info.h.

? ? ? ? ? ?一、APR File I/O介紹

? ? ? ? ? ? ? APR用了"不小的篇幅"來"描述"文件I/O,在$(APR_HOME)/file_io/unix目錄下,你會看到多個.c文件,每個.c都是一類文件I/O操作,比如:

? ? ? ? ? ? ? ? open.c --封裝了 文件的打開、關閉、改名和刪除等操作;

? ? ? ? ? ? ? ? readwrite.c -- 顧名思義,它里面包含了文件的讀寫操作;

? ? ? ? ? ? ? ? pipe.c -- 包含了pipe相關操作。

? ? ? ? ? ?二、基本APR I/O

? ? ? ? ? ? ? ?APR定義了apr_file_t類型來表示廣義的文件。先來看一下這個核心數據結構的"模樣":

/* in apr_arch_file_io.h */ struct apr_file_t {apr_pool_t *pool;int filedes;char *fname;apr_int32_t flags;int eof_hit;int is_pipe;apr_interval_time_t timeout;int buffered;enum {BLK_UNKNOWN, BLK_OFF, BLK_ON } blocking;int ungetchar; /* Last charprovided by an unget op.(-1=no char)*/ #ifndef WAITIO_USES_POLL/* if there is a timeout set, then this pollsetis used */apr_pollset_t *pollset; #endif/* Stuff for buffered mode */char *buffer;int bufpos; /*Read/Write position in buffer */unsigned long dataRead; /* a mount of valid data read into buffer */int direction; /*buffer being used for 0 = read, 1 = write */unsigned long filePtr; /*position in file of handle */ #if APR_HAS_THREADSstruct apr_thread_mutex_t *thlock; #endif };

? ? ? ? ? ? 1.apr_file_open

? ? ? ? ? ? ? ?ANSI C標準庫和Unix系統庫函數都提供對"打開文件"這個操作語義的支持。他們提供的接口很相似,參數一般都為"文件名+打開標志位+權限標志位",apr_file_open也不能忽略習慣的巨大力量,也提供了類似的接口如下:

? ? ? ? ? ? ? ? APR_DECLARE(apr_status_t) apr_file_open(apr_file_t **new,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const char *fname,?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?apr_int32_t flag,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?apr_fileperms_t perm,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?apr_pool_t *pool);

? ? ? ? ? ? ? ? ?每個封裝都有自定義的一些標志宏,這里也不例外,flag和perm參數都需要用戶傳入APR自定義的一些宏組合,這里介紹apr_file_open操作:

apr_file_open {"打開標志位"轉換; ----(1)"權限標志位"轉換; ----(2)調用Unix原生API打開文件;設置apr_file_t變量相關屬性值; ----(3) }

? ? ? ? ? ? ? ? ? (1)由于上面說了,APR定義了自己的"文件打開標志位",所以在apr_file_open的開始需要將這些專有的"文件打開標志位"轉換為Unix平臺通用的"文件打開標志位";

? ? ? ? ? ? ? ? ? ?(2)同(1)理,專有的"權限標志位"需要轉換為Unix平臺通用的"權限標志位";

? ? ? ? ? ? ? ? ? (3) APR file I/O封裝支持非阻塞I/O帶超時等待以及緩沖I/O,默認情況下為阻塞的,是否緩沖可通過"文件打開標志位"設置。一旦設置為緩沖I/O,則apr_file_open會在pool中開辟大小為APR_FILE_BUFSIZE(4096)的緩沖區供使用。

? ? ? ? ? ? ? 2.apr_file_read/apr_file_write

? ? ? ? ? ? ? ? ?該兩個接口的看點是其緩沖區管理(前提:在apr_file_open該文件時指定了是Buffer I/O及非阻塞I/O 帶超時等待)。還有一點就是通過這兩個借口的實現我們可以了解到上面提到的apr_file_t 中某些"晦澀"字段的真正含義。

? ? ? ? ? ? ? ? ? (1) 帶緩沖I/O

? ? ? ? ? ? ? ? ? ? 這里的緩沖是APR自己管理的,帶緩沖的好處很簡單,即減少直接操作文件的次數,提高I/O性能。要知道無論lseek還是read/write都是很耗時的,盡可能的減少直接I/O操作次數,會帶來性能上明顯改善。

? ? ? ? ? ? ? ? ? ?讀寫切換:如果先讀后寫,則每次寫的時候都要重新定位文件指針到上次讀的結尾處;如果先寫后讀,則每次讀前都要flush緩沖區。

? ? ? ? ? ? ? ? ? ?(2) 非阻塞I/O帶超時等待

? ? ? ? ? ? ? ? ? ? ?這里分析下面一段apr_file_read的代碼:

do {rv = read(thefile->filedes, buf, *nbytes); }while(rv == -1 && errno == EINTR); ---(a) #ifdef USE_WAIT_FOR_IOif (rv == -1 &&(errno == EAGAIN || errno == EWOULDBLOCK) &&thefile->timeout != 0) {apr_status_t arv = apr_wait_for_io_or_timeout(thefile, NULL, 1); ----(b)if (arv != APR_SUCCESS) {*nbytes = bytes_read;return arv;}else {do {rv = rad(thefile->filedes, buf, *nbytes);}while (rv == -1 && errno == EINTR);}} #endif

? ? ? ? ? ? ? ? ? ? (a) 第一個do-while塊:之所以使用do-while塊是為了當read操作被信號中斷后重啟read操作;

? ? ? ? ? ? ? ? ?(b) 一旦文件描述符設為非阻塞,(a)則瞬間返回,一旦(a)并未讀出數據,則rv = -1并且errno被設置為errno = EAGAIN,這時開始帶超時的等待該文件描述符I/O就緒。這里的apr_wait_for_io_or_timeout使用了I/O的多路 復用技術Poll,在后面的APR分析中會詳細理解之。apr_file_t中的timeout字段就是用來做超時等待的。

? ? ? ? ? ? ?3.apr_file_close

? ? ? ? ? ? ? ? 該接口主要完成的工作為刷新緩沖區、關閉文件描述符、刪除文件(如果設置了APR_DELONCLOSE標志位)和清理Pool中內存的工作。

5.6 APR分析-高級IO篇

? ? ?一、記錄鎖或(區域鎖)

? ? ? ? ? ? 我見過的對記錄鎖講解最詳細的書就是《Unix高級環境編程》,特別是關于進程、文件描述符和記錄鎖三者之間的關系的講解更是讓人受益匪淺。

? ? ? ? ? ? 關于記錄鎖的自動繼承和釋放有三條規則:

? ? ? ? ? ? (1) 鎖與進程、文件兩方面有關。這有兩重含義:第一重很明顯,當一個進程終止時,它所建立的鎖全部釋放;第二重意思就不很明顯,任何時候關閉一個描述符時,則該進程通過這一描述符可以存訪的文件上的任何一把鎖都被釋放(這些所都是該進程設置的)。

? ? ? ? ? ? ?(2) 由fork產生的子程序不繼承父進程所設置的鎖。這意味著,若一個進程得到一把鎖,然后調用fork,那么對于父進程獲得的鎖來說,子進程被視為另一個進程,對于從父進程處繼承過來的任一描述符,子進程要調用fcntl以獲得它自己的鎖。這與鎖的作用是一致的。鎖的作用是阻止多個進程同時寫同一個文件(或同一文件區域)。如果子進程繼承父進程的鎖,則父、子進程就可以同時寫同一個文件。

? ? ? ? ? ? ?(3) 在執行exec后,新程序可以繼承原執行程序的鎖。

? ? ? ? ? ? ? ? ? APR記錄鎖源碼位置在$(APR_HOME)/file_io/unix目錄下flock.c,頭文件仍然是apr_file_io.h。apr_file_lock和apr_file_unlock僅提供對整個文件的枷鎖和解鎖,而并不支持對文件中任意范圍數據的加鎖與解鎖。至于該鎖是建議鎖(advisory lock)還是強制鎖(mandatory lock),需要看具體的平臺實現了。兩個函數均利用fcntl實現記錄鎖功能。代碼中有一處值得借鑒:

while((rc = fcntl(thefile->filedes, fc, &l)) < 0 && errno == EINTR)continue;

? ? ? ? ? ? ? ? ? ? ? ?這么做的原因就是考慮到fcntl的調用可能被某信號中斷,一旦中斷我們要去重啟fcntl函數。

? ? ? ? ?二、I/O多路復用

? ? ? ? ? ? ?在經典的《Unix網絡編程第1卷》 Chapter 6中作者詳細介紹了五種I/O模型,分別為:

? ? ? ? ? ? ?- blocking I/O

? ? ? ? ? ? ?- nonblocking I/O

? ? ? ? ? ? ?- I/O multiplexing (select and poll)

? ? ? ? ? ? ?- signal driven I/O(SIGIO)

? ? ? ? ? ? ?- asynchronous I/O (the POSIX aio_functions)

? ? ? ? ? ? ?這里所說的I/O多路復用就是第三種模型,它既解決了Blocking I/O數據處理不及時,又解決了Non-Blocking I/O采用輪詢的CPU浪費問題,同時它與異步I/O不同的是它得到了各大平臺的廣泛支持。

? ? ? ? ? ? ? APR I/O多路復用源碼主要在$(APR_HOME)/poll/unix目錄下的poll.c和select.c中,頭文件為apr_poll.h。APR提供統一的apr_poll接口,但是apr_pollset_t結構定義和apr_poll的實現則根據宏POLLSET_USES_SELECT、POLL_USES_POLL和POLLSET_USES_POLL的定義與否而不同。

? ? ? ? ? ? ? ?在poll的實現下,apr_pollset_t的定義如下:

/* in poll.c */ struct apr_pollset_t {apr_pool_t *pool;apr_uint32_t nelts;apr_uint32_t nalloc;struct pollfd *pollset;apr_pollfd_t *query_set;apr_pollfd_t *result_set; };

? ? ? ? ? ? ? ? 統一的apr_pollfd_t定義如下:

/* in apr_poll.h */ struct apr_pollfd_t {apr_pool_t *p; /*associated pool*/apr_datatype_e desc_type; /*descriptor type*/apr_int16_treqevents; /*requested events*/apr_int16_trtnevents; /*returned events*/apr_descriptordesc; /* @see apr_descriptor*/void *client_data; /*allowsapp to associate context */ };

? 5.7 APR分析-共享內存篇

? ? ? ? ? ? ?共享內存是一種重要的IPC方式。在項目中多次用到共享內存,只是用而并未深入研究。

? ? ? ? ?APR共享內存封裝的源代碼的位置在$(APR_HOME)shmem目錄下,本篇blog著重分析unix子目錄下的shm.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_shm.h.

? ? ? ? ?一、共享內存簡單小結

? ? ? ? ? ? 共享內存時最快的IPC方式,因為一旦這樣的共享內存段映射到各個進程的地址空間,這些進程間通過共享內存的數據傳遞就不需要內核的幫忙了。Stevens的解釋是"各進程不是通過執行任何進入內核的系統調用來傳遞數據,顯然內核的責任僅僅是建立各進程地址空間與共享內存的映射,當然像處理頁面故障這一類的底層活還是要做的"。相比之下,管道和消息隊里交換數據時都需要內核來中轉數據,速度就相對較慢。

? ? ? ? ?二、APR共享內存封裝

? ? ? ? ? ? ? APR提供多種創建共享內存的方式,其中最主要的就是apr_shm_create接口,其偽碼如下:? ? ??

apr_shm_create {if (要創建匿名shm) { #if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON #if APR_USE_SHMEM_MMAP_ZEROxxxx ---------(1) #elif APR_USE_SHMEM_MMAP_ANONxxxx ----------(2) #endif #endif /* APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON */ #if APr_USE_SHMEM_SHMGET_ANONxxxx ----------(3) #endif } else { /* 創建有名shm */ #if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM #if APR_USE_SHMEM_MMAP_TMPxxxx --------(4) #endif #if APR_USE_SHMEM_MMAP_SHMxxxx ----------(5) #endif #endif /* APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM */ #if APR_USE_SHMEM_SHMGETxxxx -----------(6) #endif} }

? ? ? ? ? ? ?其中不同版本Unix創建匿名shmem的做法如下:

? ? ? ? ? ? ?(1) SVR4通過映射"/dev/zero"設備文件來獲得匿名共享內存,其代碼一般為:

fd = open("/dev/zero", ..); ptr = mmap(..., MAP_SHARED, fd, ...);

? ? ? ? ? ? ?(2) 4.4 BSD提供更加簡單的方式來支持匿名共享內存(注意標志參數MAP_XX)

ptr = mmap(..., MAP_SHARED | MAP_ANON, -1, ...);

? ? ? ? ? ? ?(3) System V匿名共享內存區的做法如下:

shmid = shmget(IPC_PRIVATE, ...); ptr = shmat(shmid, ...);

? ? ? ? ? ? ? ? 匿名共享內存一般都用于有親緣關系的進程間的數據通訊。由父進程創建共享內存,子進程自動繼承下來。由于是匿名,沒有親緣關系的進程是不能動態鏈接到該共享內存區的。

? ? ? ? ? ? ? 不同版本Unix創建有名shmem的做法如下:

? ? ? ? ? ? ? (4) 由于是有名的shmem,所以與匿名不同的地方在于用filename替代"/dev/zero"做映射。

fd = open(filename, ...); apr_file_trunc(...); ptr = mmap(..., MAP_SHARED, fd, ...);

? ? ? ? ? ? ? (5) Posix共享內存的做法

fd = shm_open(filename, ...); apr_file_trunc(...); ptr = mmap(..., MAP_SHARED, fd, ...);

? ? ? ? ? ? ? ? ? 值得注意的一點就是通過shm_open映射的共享內存可以供無親緣關系的進程共享。apr_file_trunc用于重新設定共享內存對象長度。

? ? ? ? ? ? ? ?(6) System V有名共享內存區的做法如下:

shmkey = ftok(filename, 1); shmid = shmget(shmkey, ...); //相當于open orshm_open ptr = shmat(shmid, ...); //相當于mmap

? ? ? ? ? ? ? ?有名共享內存一般都與一個文件相關,該文件映射到共享內存段,而不同的進程(包括無親緣關系的進程)則都映射到該文件以達到目的。在APR中通過apr_shm_attach可以動態將調用進程連接到已存在的共享內存上,前提是你必須知道該共享內存區的標識,在APr中一律用filename做標識。

? ? ? ? 三、總結

? ? ? ? ? ? 內核架起了多個進程間共享數據的紐帶--共享內存。通過上面的敘述你會發現共享內存的創建其實并不困難,真正困難的是共享內存的管理,在正規的軟件公司像內存/共享內存管理這樣的重要底層功能都是封裝成庫形式的。

? ? ? ? 四、參考資料

? ? ? ? ? ? SIGSEGV和SIGBUS

? ? ? ? ? ? 涉及共享內存的管理就不能不提到訪問共享內存對象。談到訪問共享內存對象就要留神"SIGSEGV和SIGBUS"這兩個信號。

? ? ? ? ? ? ? 系統分配內存頁來承載內存映射區,由于內存頁大小是固定的,所以存在多余的頁空間空閑,比如待映射文件大小為5000 bytes,內存映射區大小也為5000bytes。而一個內存頁大小4096,系統勢必要分配兩頁來承載,這時空閑的有效空間為從5000-8191,如果進程訪問這段地址空間也不會發生錯誤。但是要超出8191,就會收到SIGSEGV信號,導致程序停止。關于SIGBUS信號的來歷,這里也舉例說明:若待映射文件大小為5000 bytes,我們在mmap時指定內存映射區size = 15000 > 5000,這時內核真正的共享區承載體大小只有8192(能包容映射文件大小即可),此時在[0, 8191]內訪問均沒問題,但在[8192,14999]之間會得到SIGBUS信號;超出15000訪問時會觸發SIGSEGV信號。

? 5.8 APR分析-環篇

? ? ? ? ? APR中少見對數據結構的封裝,好像唯一例外的就是其對循環鏈表,即環(RING)的封裝。

? ? ? ? ? 簡單說說環(RING):環是一個首尾相連的雙線鏈表,也就是我們所說的循環鏈表。

? ? ? ? ? 1.如何使用APR RING?

假設環節點的結構如下: struct elem_t { /* APR RING鏈接的元素類型定義 */APR_RING_ENTRY(elem_t) link; /*鏈接域*/int foo; /*數據域*/ }; APR_RING_HEAD(elem_head_t, elem_t); int main() {struct elem_head_t head;struct elem_t *el;APR_RING_INIT(&head, elem_t, link);/* 使用其他操作宏插入、刪除等操作,例如*/el = malloc(sizeof(elem_t);el->foo = 20051103;APR_RING_ELEM_INIT(el, link);APR_RING_INSERT_TAIL(&h, el, elem_t, link); }

? ? ? ? ? ? 2.APR RING的難點---"哨兵"

? ? ? ? ? ?環是通過頭節點來管理的,頭節點是這樣一種節點,其next指針指向RING的第一個節點,其prev指針指向RING的最后一個節點,即尾節點。但是通過查看源碼發現APR RING通過APR_RING_HEAD宏定義的頭節點形式如下:

#define APR_RING_HEAD(head, elem) /struct head { /struct elem *next; /struct elem *prev; /}

? ? ? ? ? ? ?如果按照上面的例子進行宏展開,其形式如下:

struct elem_head_t {struct elem_t *next;struct elem_t *prev; };

? ? ? ? ? ? ? 而一個普通的元素elem_t 展開形式如下:

struct elem_t {struct { /struct elem_t *next; /struct elem_t *prev; /} link;int foo; };

? ? ? ? ? ? ? 通過對比可以看出頭節點僅僅相當于一個elem_t的link域。這樣做的話必然帶來對普通節點和頭節點在處理上的不一致,為了避免這種情況的發生,APR RING引入了"哨兵"節點的概念。我們先看看哨兵節點在整個鏈表中的位置。

? ? ? ? ? ? ? ? sentinel->next = 鏈表的第一個節點;

? ? ? ? ? ? ? ? sentinel->prev = 鏈表的最后一個節點;

? ? ? ? ? ? ? ? 但是查看APR RING的源碼你會發現sentinel節點只是個虛擬存在的節點,這個虛擬節點既有數據域(虛擬出來的,不能引用)又有鏈接域,好似與普通節點并無差別。

? ? ? ? ? ? ? ? ?再看看下面APR_RING_INIT的源代碼:

#define APR_RING_INIT(hp, elem, link) do{ /APR_RING_FIRST((hp)) = APR_RING_SENTINEL((hp), elem, link); /APR_RING_LAST((hp)) = APR_RING_SENTINEL((hp), elem, link); / }while(0)

? ? ? ? ? ? ? ? ? 你會發現:初始化RING實際上是將head的next和prev指針都指向了sentinel虛擬節點了。從sentinel的角度來說相當于其自己的link域的next和prev都指向了自己。所以判斷APR RING是否為空只需要判斷RING的首個節點是否為sentinel虛擬節點即可。APR_RING_EMPTRY宏就是這么做的:

#define APR_RING_EMPTY(hp, elem, link) /(APR_RING_FIRST((hp)) == APR_RING_SENTINEL((hp), elem, link))

? ? ? ? ? ? ? ? ? ?那么如何計算sentinel虛擬節點的地址呢?

? ? ? ? ? ? ? ? ? ?我們這樣思考:從普通節點說起,如果我們知道一個普通節點的首地址(elem_addr),那么我們計算其link域的地址(link_addr)的公式就應該為link_addr=elem_addr + offsetof(elem_t, link);前面我們一直在說sentinel虛擬節點看起來和普通節點沒什么區別,所以它仍然符合該計算公式。前面我們又說過head_addr是sentinel節點的link域,這樣的話我們將head_addr輸入到公式中得到head_addr = sentinel_addr + offsetof(elem_t, link),做一下變換即可得到sentinel_addr = head_addr - offsetof(elem_t, link)??纯碅PR RING源代碼就是這樣實現的:

#define APR_RING_SENTINEL(hp, elem, link) /(struct elem *)((char *)(hp) - APR_OFFSETOF(struct elem, link))

? ? ? ? ? ? ? ? ? ? ?至此APR RING使用一個虛擬sentinel節點分隔RING的首尾節點,已達到對節點操作一致的目的。

? ? ? ? ? ? ? ? ?3、APR RING不足之處

? ? ? ? ? ? ? ? ? ? 1)缺少遍歷接口

? ? ? ? ? ? ? ? ? ? ? ?瀏覽APR RING源碼后發現缺少一個遍歷宏接口,這里提供一種正向遍歷實現:

#define APR_RING_TRAVERSE(ep, hp, elem, link) /for ((ep) = APR_RING_FIRST((hp)); /(ep) != APR_RING_SENTINEL((hp), elem, link); /(ep) = APR_RING_NEXT((ep), link))

? 5.9 APR分析-進程同步篇

  • 最新的統計數據顯示Apache服務器在全世界仍然占據著Web服務器龍頭老大的位置,而且市場占有率遙遙領先,所以學習Apache相關知識是完全正確的方向,這里我們繼續分析APR進程同步相關內容。

? ? ? ? ?進程同步的源代碼的位置在$(APR_HOME)/locks目錄下,本篇blog著重分析unix子目錄下的proc_mutex.c、global_mutex文件內容,其相應頭文件為$(APR_HOME)/include/apr_proc_mutex.h、apr_global_mutex.h。其用于不同進程之間的同步以及多進程多線程中的同步問題。

? ? ? ? ? ? ?apr_thread_mutex_t - 支持單個進程內的多線程同步;

? ? ? ? ? ? ?apr_proc_mutex_t - 支持多個進程間的同步;

? ? ? ? ? ? ?apr_global_mutex_t - 支持不同進程內的不同線程間同步。

? ? ? ? ? ? ?在本篇中著重分析apr_proc_mutex_t。

? ? ? ? 1.同步機制

? ? ? ? ? APR提供多種進程同步的機制供選擇使用。在apr_proc_mutex.h中列舉了如下同步機制:

typedef enum {APR_LOCK_FCNTL, /*記錄上鎖*/APR_LOCK_FLOCK, /* 文件上鎖*/APR_LOCK_SYSVSEM, /*系統V信號量*/APR_LOCK_PROC_PTHREAD, /* 利用pthread線程鎖特性*/APR_LOCK_POSIXSEM, /*POSIX信號量*/APr_LOCK_DEFAULT /*默認進程間鎖*/ } apr_lockmech_e;

? ? ? ? ?2.實現點滴

? ? ? ? ? ?APR提供每種同步機制的實現,每種機制體現為一組函數接口,這些接口被封裝在一個結構體類型中:

/* in apr_arch_proc_mutex.h */ struct apr_proc_mutex_unix_lock_methods_t {unsigned int flags;apr_status_t (*create)(apr_proc_mutex_t *, const char *);apr_status_t (*acquire)(apr_proc_mutex_t *);apr_status_t (*tryacquire)(apr_proc_mutex_t *);apr_status_t (*release)(apr_proc_mutex_t *);apr_status_t (*cleanup)(void *);apr_status_t (*child_init)(apr_proc_mutex_t **, apr_pool_t *, const char *);const char *name; };

? ? ? ? ? ?之后在apr_proc_mutex_t類型中,apr_proc_mutex_unix_lock_methods_t的出現也就在清理之中了

/* in apr_arch_proc_mutex.h */ struct apr_proc_mutex_t {apr_pool_t *pool;const apr_proc_mutex_unix_lock_methods_t *meth;const apr_proc_mutex_unix_lock_methods_t *inter_meth;int curr_locked;char *fname;... ... #if APR_HAS_PROC_PTHREAD_SERIALIZEpthread_mutex_t *pthread_interproc; #endif };

? ? ? ? ?這樣APR提供的用戶接口其實就是對mech各個"成員函數"功能的"薄封裝",而真正干活的其實是apr_proc_mutex_t中的meth字段的"成員函數",它們的工作包括mutex的創建、獲取(加鎖)和清除(解鎖)等。以"獲取鎖"為例APR的實現如下:

APR_DECLARE(apr_status_t) apr_proc_mutex_lock(apr_proc_mutex_t *mutex) {return mutex->meth->acquire(mutex); }

? ? ? ? ?3.同步機制

? ? ? ? ? 按照枚舉類型apr_lockmech_e的聲明,我們知道APR為我們提供了5中同步機制,下面分別說說:

? ? ? ? ? (1) 記錄鎖

? ? ? ? ? ? ?記錄鎖是一種建議性鎖,它不能防止一個進程寫已由另一個進程上了讀鎖的文件,它主要利用fcntl系統調用來完成鎖功能的,記得在以前的一篇關于APR文件I/O的Blog中談過記錄鎖,這里不再詳細敘述了。

? ? ? ? ? (2) 文件鎖

? ? ? ? ? ? ? 文件鎖是記錄鎖的一個特例,其功能由函數接口flock支持。值得說明的是它僅僅提供"寫入鎖"(獨占鎖),而不提供"讀入鎖"(共享鎖)。

? ? ? ? ? ?(3) System V信號量

? ? ? ? ? ? ? System V信號量是一種內核維護的信號量,所以我們只需調用semget獲取一個System V信號量的描述符即可。值得注意的是與POSIX的單個"計數信號量"不同的是System V信號量是一個"計數信號量集"。? ?

? ? ? ? ? ?(4) 利用線程互斥鎖機制

? ? ? ? ? ? ? APR使用pthread提供的互斥鎖機制。原本pthread互斥鎖是用來互斥一個進程內的各個現成的,但APR在共享內存中創建了pthread_mutex_t,這樣使得不同進程的主線程實現互斥,從而達到進程間互斥的目的。截取部分代碼如下:

new_mutex->pthread_interproc = (pthread_mutex_t *)mmap((caddr_t)0,sizeof(pthread_mutex_t),PROT_READ | PROT_WRITE, MAP_SHARED,fd, 0);

? ? ? ? ? ? (5) POSIX信號量

? ? ? ? ? ? ? ?APR使用了POSIX有名信號量機制,下面代碼舉例說明:

/* in proc_mutex.c */ apr_snprintf(semname, sizeof(semname), "/ApR.%lxZ%lx", sec, usec); /* APR自定義一種POSIX信號量命名規則*/ psem =sem_open(semname, O_CREAT, 0644, 1);

? ? ? ? ? ?4.如何使用

? ? ? ? ? ? ?我們知道父進程的鎖其子進程并不繼承。APR進程同步機制的一個典型使用方法就是:"Create the mutex in the Parent, Attach to in the Child"。APR提供接口apr_proc_mutex_child_init在子進程中reopen themutex。

? 5.10 APR分析-線程篇

? ? ? ? ? 并行一直是程序設計領域的難點,而線程是并行的一種重要的手段,而且現成的一些特性也能在進程并行時發揮很好的作用(“在線程同步篇”中詳細闡述)。

? ? ? ? APR線程的源代碼的位置在$(APR_HOME)/threadproc目錄下,本篇blog著重分析unix子目錄下的thread.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_threadproc.h。

? ? ? ? ? 一、線程基礎

? ? ? ? ? ? ? (1) 在傳統觀點中,進程是由存儲于用戶虛擬內存中的代碼、數據和棧,以及由內核維護的"進程上下文"組成的,其中"進程上下文"又可以看成"程序上下文"和"內核上下文"組成,可參見下圖所示:

進程--|- 進程上下文|-程序上下文|-數據寄存器|-條件碼|-棧指針|-程序計數器|- 內核上下文|- 進程ID|- VM結構|- Open files|- 已設置的信號處理函數|- brk pointer|- 代碼、數據和棧(在虛存中)|- 棧區<--SP|- 共享庫區|- 運行時堆區 <--brk|- 可讀/寫數據區|- 只讀代碼/數據區 <--PC

? ? ? ? ? ? ? ?(2) 另一種觀點中,進程是由線程、代碼和數據以及內核上下文組成的。下圖更能直觀的展示出兩種觀點的異同:

進程--+|- 線程|- 棧區 <--SP|- 線程上下文|- 線程ID|- 數據寄存器|- 條件碼|- 棧指針|- 程序計數器|- 內核上下文|- 進程ID|- VM結構|- Open files|-已設置的信號處理函數|- brk pointer|- 代碼、數據(在虛存中)|- 共享庫區|- 運行時堆區 <-- brk|- 可讀/寫數據區|- 只讀代碼/數據區 <--PC

? ? ? ? ? ? ? ?對比兩種觀點我們可以得出以下幾點結論:

? ? ? ? ? ? ?(a) 從觀點(2)可以看出進程內的多個線程共享進程的內核上下文和代碼、數據(當然不包括棧區);

? ? ? ? ? ? ?(b) 線程上下文比進程上下文小,且切換代價小;

? ? ? ? ? ? ?(c) 線程不像進程那樣有著"父-子"體系,同一個進程內的線程都是"對等的",主線程與其他線程不同之處就在于其是進程創建的第一個線程。

? ? ? ? ?二、APR線程管理接口

? ? ? ? ? ? ?如今應用最廣泛的線程包就是PosixThread了。APR對線程的封裝也是基于Posix thread的。

? ? ? ? ? ? ?APR線程管理接口針對apr_thread_t 這個基本的數據結構進行操作,apr_thread_t的定義很簡單:

/* apr_arch_threadproc.h */ struct apr_thread_t {apr_pool_t *pool;pthread_t *td;void *data;apr_thread_start_t func;apr_status_t exitval; };

? ? ? ? ? ? ?這個結構中包含了線程ID、線程函數以及該函數的參數數據。不過APR的線程函數定義與Pthread的有不同,“Pthread線程函數”是這樣的:

? ? ? ? ? typedef void *(start_routine)(void *);

? ? ? ? ? ?而"APR線程函數"如下:

? ? ? ? ? typedef void *(APR_THREAD_FUNC *apr_thread_start_t)(apr_thread_t *, void *);

? ? ? ? ?1.apr_thread_create

? ? ? ? ? ? apr_thread_create 內部定義了一個dummy_worker的"Pthread線程函數",并將apr_thread_t結構作為參數傳入,然后在dummy_worker中啟動"APR的線程函數"。在該函數的參數列表中有一項類型為apr_threadattr_t:

struct apr_threadattr_t {apr_pool_t *pool;pthread_attr_t attr; };

? ? ? ? ? 2.apr_thread_exit

? ? ? ? ? ? ? 進程退出我們可以直接調用exit函數,而線程退出也有幾種方式:

? ? ? ? ? ? ?(1) 隱式退出 - 可以理解為線程main routine代碼結束返回;

? ? ? ? ? ? ?(2) 顯式退出 - 調用線程包提供的顯示退出接口,在apr中就是apr_thread_exit;

? ? ? ? ? ? ?(3) 另類顯式退出 - 調用exit函數,不僅自己退出,其所在線程也跟著退出了;

? ? ? ? ? ? ?(4)被"黑"退出 - 被別的"對等"線程調用pthread_cancel而被迫退出。

? ? ? ? ? ? ?apr_thread_exit屬于種類(2),該種類退出應該算是線程的優雅退出了。apr_thread_exit做了3個工作,分別為設置線程返回值、釋放pool中資源和調用pthread_exit退出。

? ? ? ? ? ? 3.apr_thread_join和apr_thread_detach

? ? ? ? ? ? ? 進程有waitpid,線程有join。線程在調用apr_thread_exit后,只是其執行停止了,其占有的"資源"并不一定釋放,這里的"資源"我想就是"另種觀點"中的"線程上下文",線程有兩種方式來釋放該"資源",這主要由現成的"可分離"屬性決定的。如果線程是"可分離的",當線程退出后會自動釋放其"資源",如果線程為"非可分離的",則必須由"對等線程"調用join接口來釋放其資源。apr_thread_detach用來將其調用線程轉化為"可分離"線程,而apr_thread_join用來等待某個線程結束并釋放其資源。

? 5.11 APR分析-網絡IO篇

? ? ? ? ?APR網絡I/O的源代碼的位置在$(APR_HOME)/network_io目錄下,本篇blog著重分析unix子目錄下的各.c文件內容,其相應頭文件為$(APR_HOME)/include/apr_network_io.h。

? ? ? ?一、IP地址 -- 主機通信

? ? ? ? ? ?我們熟知的并且每天工作于其上的因特網是一個世界范圍的主機的集合,這個主機結合被映射為一個32位(目前)或者64位(將來)IP地址;而IP地址又被映射為一組因特網域名;一個網絡中的主機上的進程能通過一個連接(connection)和任何其他網絡中的主機上的進程通信。

? ? ? ? ? 1.IP地址存儲

? ? ? ? ? ? ?在如今的IPv4協議中我們一般使用一個unsigned int來存儲IP地址,在UNIX平臺下,使用如下結構來存儲一個IP地址的值:

/* Internet address structure */ struct in_addr {unsigned int s_addr; /* network byte order(big-endian) */ };

? ? ? ? ? ? ?這里值得一提的是APR關于IP地址存儲的做法,看如下代碼:

#if (!APR_HAVE_IN_ADDR) /*We need to make sure we always have an in_addr type, so APR will just define it ourselves, if the platform doesn't provide it. */ struct in_addr {apr_uint32_t s_addr; }; #endif

? ? ? ? ? ? ? APR保證了其所在平臺上in_addr的存在。在in_addr中,s_addr是以網絡字節序存儲的。如果你的IP地址不符合條件,可通過調用一些輔助接口來做轉換,這些接口包括:

htonl: host to network long; htons: host to network short; ntohl: network to host long; ntohs: network to host short.

? ? ? ? ? ? ? 2.IP地址表示

? ? ? ? ? ? ? ?我們平時看到的IP地址都是類似"xxx.xxx.xxx.xxx"這樣的點分十進制的。上面說過IP地址使用的是一個unsigned int整形數來表示。這樣就存在著一個IP地址表示和IP地址存儲之間的一個轉換過程。APR提供這一轉換支持,我們用一個例子來說明:

#include <apr.h> #include <apr_general.h> #include "apr_network_io.h" #include "apr_arch_networkio.h" int main(int argc, const char *const *argv, const char *const *env) {apr_app_initialize(&argc, &argv, &env);char presentation[100];int networkfmt;memset(presentation, 0, sizeof(presentation));apr_inet_pton(AF_INET, "255.255.255.255", &networkfmt);printf("0x%x/n", networkfmt);apr_inet_ntop(AF_INET, &networkfmt, presentation, sizeof(presentation));printf("presentation is %s/n", presentation);apr_terminate();return 0; }

? ? ? ? ? ? ? ?APR提供apr_inet_pton將我們熟悉的點分十進制形式轉換成一個整形數存儲的IP地址;而apr_inet_ntop則將一個存整形數存儲的IP地址轉換為我們可讀的點分十進制形式。這兩個接口的功能類似于系統調用inet_pton和inet_ntop,至于使用哪個就看你的喜好了。

? ? ? ?二、SOCKET --進程通信

? ? ? ? ? ?1.SOCKET描述符

? ? ? ? ? ? ? 獲取SOCKET描述符:

int socket(int domain, int type, int protocol);

? ? ? ? ? ? ? 從Unix程序的角度來看,SOCKET就是一個有相應描述符的打開的文件。在APR中我們可以通過調用apr_socket_create來創建一個APR自定義的SOCKET對象,該SOCKET結構如下:

/* apr_arch_networkio.h*/ struct apr_socket_t {apr_pool_t *cntxt;int socketdes;int type;int protocol;apr_sockaddr_t *local_addr;apr_sockaddr_t *remote_addr;apr_interval_time_t timeout; #ifdef HAVE_POLLint connected; #endifint local_port_unknown;int local_interface_unknown;int remote_addr_unknown;apr_int32_t options;apr_int32_t inherit;sock_userdata_t *userdata; #ifndef WAITIO_USES_POLL/* if there is a timeout set, then this pollset is used */apr_pollset_t *pollset; #endif };

? ? ? ? ? ? ? ? ? ? ? ?該結構中的socketdes字段其實是真實存儲由socket函數返回的SOCKET描述符的,其他字段都是為APR自己所使用的,這些字段在Bind、Connect等過程中使用。我們如果不顯示將SOCKET描述符綁定到某SOCKET地址上,系統內核就會自動為該SOCKET描述符分配一個SOCKET地址。

? ? ? ? ? ? 2.SOCKET屬性

? ? ? ? ? ? ? ? 還是與文件對比,在文件系統調用中有一個fcntl接口可以從來獲取或設置已分配的文件描述符的屬性,如是否Block、是否Buffer等。SOCKET也提供類似的接口調用setsockopt和getsockopt。在APR中等價于該功能的接口時apr_socket_opt_set和apr_socket_opt_get。APR在apr_network_io.h中提供如下SOCKET的參數屬性:

#define APR_SO_LINGER 1 /*Linger*/ #define APR_SO_KEEPALIVE 2 /*Keepalive*/ #define APR_SO_DEBUG 4 /*Debug*/ #define APR_SO_NONBLOCK 8 /*Non-blocking IO*/ #define APR_SO_REUSEADDR 16 /*Reuse addresses*/ #define APR_SO_SNDBUF 64 /*Send buffer*/ #define APR_SO_DISCONNECTED 256 /*Disconnected*/ ......

? ? ? ? ? ?另外從上面這些屬性值(都是2的n次方)可以看出SOCKET也是使用一個屬性控制字段中的"位"來控制SOCKET屬性的。

? ? ? ? ? ?再有APR提供一個宏apr_is_option_set來判斷一個SOCKET是否擁有某個屬性。

? ? ? ? ? ? 3.Connect、Bind、Listen、Accept-- 建立連接

? ? ? ? ? ? ? (1) apr_socket_connect

? ? ? ? ? ? ? ?客戶端連接服務器端的唯一調用就是connect,connect試圖建立一個客戶端進程與服務器端進程的連接。apr_socket_connect的參數分別為客戶端已經打開的一個SOCKET以及指定的服務器端的SOCKET地址(IP ADDR:PORT)。apr_socket_connect內部實現的流程大致如下:

apr_socket_connect {do {rc = connect(sock->socketdes,(const struct sockaddr *)&sa->sa.sin,sa->salen);} while (rc == -1 && errno == EINTR); ---(a)if ((rc == -1) && (errno == EINPROGRESS || errno == EALREADY)&& (sock->timeout > 0)) {rc = apr_wait_for_io_or_timeout(NULL, sock, 0); ----(b)if (rc != APR_SUCCESS) {return rc;}if (rc == -1 && errno != EISCONN) {return errno; ----(c)}初始化sock->remote_addr;... ... }

? ? ? ? ? ? ? ? ? 對上述代碼進行若干說明:

? ? ? ? ? ? ? (a) 執行系統調用connect連接服務器端,注意這里做了防止信號中斷的處理。

? ? ? ? ? ? ? (b) 如果系統操作正在進行中,調用apr_wait_for_io_or_timeout進行超時等待;

? ? ? ? ? ? ? (c) 錯誤返回,前提errno不是表示已連接上。

? ? ? ? ? ? ? 一旦apr_socket_connect成功返回,我們就已經成功建立一個SOCKET對,即一個連接。

? ? ? ? ?(2) apr_socket_bind

? ? ? ? ? ? ? Bind、Listen和Accept這三個過程是服務器端用于接收"連接"的必經之路。其中Bind就是告訴操作系統內核顯示地位該SOCKET描述符分配一個SOCKET地址,這個SOCKET地址就不能被其他SOCKET描述符占用了。

? ? ? ? ?(3)apr_socket_listen

? ? ? ? ? ? ?SOCKET描述符在初始分配時都處于"主動連接"狀態,Listen過程將該SOCKET描述符從"主動連接"轉換為"被動狀態",并告訴內核接受該SOCKET描述符的連接請求。apr_socket_listen的背后直接就是listen接口調用。

? ? ? ? ? (4) apr_socket_accept

? ? ? ? ? ? ? Accept過程在"被動狀態"SOCKET描述符上接受一個客戶端的連接,這時系統內核會自動分配一個新的SOCKET描述符,內核為該描述符自動分配一個SOCKET地址,來代表這條連接的服務器端。注意在SOCKET編程接口中除了socket函數能分配新的SOCKET描述符之外,accept也是另外的一個也是唯一的一個能分配新的SOCKET描述符的系統調用了。apr_socket_accept首先在pool中分配一個新的apr_socket_t結構變量,然后調用accept,并設置新變量的各個字段。

? ? ? ? ? ? 4.Send/Recv --數據傳輸

? ? ? ? ? ? ? 網絡通信最重要的還是數據傳輸,在SOCKET編程接口中最常見的兩個接口就是recv和send。在APR中分別有apr_socket_recv和apr_socket_send與前面二者對應。下面逐一分析。

? ? ? ? ? ? ? ?(1) apr_socket_recv

? ? ? ? ? ? ? ? ?首先來看看apr_socket_recv的實現過程:

? ? ? ? ? ? ? ? ?

apr_socket_recv {if (上次調用apr_socket_recv沒有讀完所要求的的字節數) { ----------(a)設置sock->options;goto do_select;}do {rv = read(sock->socketdes, buf, (*len)); ------(b)} while (rv == -1 && errno == EINTR);if ((rv == -1) && (errno == EAGAIN || errno == EWOULDBLOCK) && (sock->timeout > 0)) { do_select:arv = apr_wait_for_io_or_timeout(NULL, sock, 1);if (arv != APR_SUCCESS) {*len = 0;return arv;}else {do {rv = rad(sock-》socketdes,buf, (*len));} while(rv == -1 && errno == EINTR);}} ---------(c)設置(*len)和sock->options; -----(d)... ... }

? ? ? ? ? ? ? ? ? ? ? ?針對上面代碼進行說明:

? ? ? ? ? ? ? ? ? ? ? ?(a) 一次apr_socket_recv調用完全有可能沒有讀完所要求的字節數,這里做個判斷以決定是否繼續讀完剩下的數據;

? ? ? ? ? ? ? ? ? ? ? ? (b) 調用read讀取SOCKET緩沖區數據,注意這里做了防止信號中斷的處理。

? ? ? ? ? ? ? ? ? ? ? ? (c) 如果SOCKET操作正忙,我們調用apr_wait_for_io_or_timeout等待,直到SOCKET可用。

? ? ? ? ? ? ? ? ? ? ? ? (d) 將(*len)設置為實際從SOCKET Buffer中讀取的字節數,并根據這一實際數據與要求數據作比較來設置sock->options.

? ? ? ? ? ? ? (2) apr_socket_send

? ? ? ? ? ? ? ? ? ? apr_socket_send負責發送數據到SOCKET Buffer,其實現的方式與apr_socket_recv大同小異。

? ? ? ? ? ? ? ? ?

總結

以上是生活随笔為你收集整理的参考资料学习APR库的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

国产艳妇av在线观看果冻传媒 | 日韩av无码一区二区三区不卡 | 无码免费一区二区三区 | 天堂久久天堂av色综合 | 日韩欧美成人免费观看 | 午夜福利一区二区三区在线观看 | 国产莉萝无码av在线播放 | 国产色在线 | 国产 | 无码成人精品区在线观看 | 日韩欧美中文字幕公布 | 国产精品久久久久9999小说 | 一本久久a久久精品vr综合 | 亚洲国产高清在线观看视频 | 在线播放免费人成毛片乱码 | 性生交大片免费看女人按摩摩 | 日日鲁鲁鲁夜夜爽爽狠狠 | 亚洲 激情 小说 另类 欧美 | 日日麻批免费40分钟无码 | 国产色xx群视频射精 | 国内精品人妻无码久久久影院蜜桃 | 老熟妇仑乱视频一区二区 | 天天燥日日燥 | 久久久久久九九精品久 | 亚洲精品一区二区三区大桥未久 | 中文字幕无码热在线视频 | 久久综合给合久久狠狠狠97色 | 天堂а√在线地址中文在线 | 国产又爽又黄又刺激的视频 | 日本大香伊一区二区三区 | 日韩欧美群交p片內射中文 | 日韩av无码中文无码电影 | 丰满少妇女裸体bbw | 精品亚洲成av人在线观看 | 激情国产av做激情国产爱 | 无码人妻少妇伦在线电影 | 亚洲欧洲日本综合aⅴ在线 | 国产成人无码午夜视频在线观看 | 亚洲 另类 在线 欧美 制服 | 欧美一区二区三区视频在线观看 | 少妇性l交大片欧洲热妇乱xxx | 国色天香社区在线视频 | 国产 浪潮av性色四虎 | 爆乳一区二区三区无码 | 亚洲 另类 在线 欧美 制服 | 鲁鲁鲁爽爽爽在线视频观看 | 国产精品亚洲lv粉色 | 国产精品99久久精品爆乳 | 色五月五月丁香亚洲综合网 | 国产色视频一区二区三区 | 东北女人啪啪对白 | 国产内射老熟女aaaa | 中文字幕日韩精品一区二区三区 | 人妻aⅴ无码一区二区三区 | 美女黄网站人色视频免费国产 | 国产精品igao视频网 | 永久黄网站色视频免费直播 | 俄罗斯老熟妇色xxxx | 成人aaa片一区国产精品 | 一本久久伊人热热精品中文字幕 | 亚洲成a人一区二区三区 | 国产激情一区二区三区 | 国产人妻精品一区二区三区不卡 | 嫩b人妻精品一区二区三区 | 日韩精品乱码av一区二区 | 欧美精品在线观看 | 久久人人爽人人爽人人片ⅴ | 亚洲 高清 成人 动漫 | 动漫av一区二区在线观看 | 亚洲色大成网站www国产 | 天天爽夜夜爽夜夜爽 | 人人爽人人澡人人人妻 | 亚洲精品一区二区三区四区五区 | 国产精品无码一区二区三区不卡 | 国产香蕉尹人视频在线 | 动漫av一区二区在线观看 | 亚洲日韩乱码中文无码蜜桃臀网站 | 欧美国产日韩久久mv | 亚洲日韩av一区二区三区中文 | 伊在人天堂亚洲香蕉精品区 | 丁香花在线影院观看在线播放 | 国产精品久久久久久亚洲毛片 | 玩弄少妇高潮ⅹxxxyw | ass日本丰满熟妇pics | 精品国产乱码久久久久乱码 | 国产精品a成v人在线播放 | 人人妻人人澡人人爽欧美一区 | 婷婷丁香六月激情综合啪 | 少妇人妻偷人精品无码视频 | 国产午夜福利100集发布 | 亚洲综合久久一区二区 | 一本精品99久久精品77 | 中文字幕乱码人妻无码久久 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 色婷婷久久一区二区三区麻豆 | 欧洲精品码一区二区三区免费看 | 丰满少妇弄高潮了www | 99久久久无码国产aaa精品 | 高潮毛片无遮挡高清免费视频 | 亚洲人成网站色7799 | 欧美高清在线精品一区 | 麻豆果冻传媒2021精品传媒一区下载 | 久9re热视频这里只有精品 | 国产亚洲精品久久久久久 | 在线а√天堂中文官网 | 免费网站看v片在线18禁无码 | 国产精品视频免费播放 | 丝袜人妻一区二区三区 | 大地资源中文第3页 | 男女猛烈xx00免费视频试看 | 国产成人无码a区在线观看视频app | 成人无码视频免费播放 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产成人综合色在线观看网站 | 少妇无码av无码专区在线观看 | 亚洲国产精品久久人人爱 | 日韩 欧美 动漫 国产 制服 | 人妻无码久久精品人妻 | 女高中生第一次破苞av | 高潮毛片无遮挡高清免费视频 | 内射后入在线观看一区 | 国产精品免费大片 | 激情内射亚州一区二区三区爱妻 | 精品厕所偷拍各类美女tp嘘嘘 | 国产在线一区二区三区四区五区 | 亚洲人成无码网www | 久久婷婷五月综合色国产香蕉 | 国产精品国产三级国产专播 | 成年美女黄网站色大免费全看 | v一区无码内射国产 | 成人动漫在线观看 | 乱码午夜-极国产极内射 | 大乳丰满人妻中文字幕日本 | 日本大乳高潮视频在线观看 | 夜精品a片一区二区三区无码白浆 | 麻豆成人精品国产免费 | 国产亚洲美女精品久久久2020 | 久久综合网欧美色妞网 | 秋霞特色aa大片 | 午夜精品一区二区三区在线观看 | 麻豆av传媒蜜桃天美传媒 | 99久久无码一区人妻 | 搡女人真爽免费视频大全 | 日本爽爽爽爽爽爽在线观看免 | 日本爽爽爽爽爽爽在线观看免 | 在线精品国产一区二区三区 | 国产午夜手机精彩视频 | 亚洲日本va中文字幕 | 国产偷国产偷精品高清尤物 | 国产另类ts人妖一区二区 | 日产精品高潮呻吟av久久 | 性史性农村dvd毛片 | 2020久久香蕉国产线看观看 | 国产精品99爱免费视频 | 天堂亚洲2017在线观看 | 国产人妻精品午夜福利免费 | 麻豆蜜桃av蜜臀av色欲av | 国产人妻精品一区二区三区 | www国产亚洲精品久久网站 | 国产人妻人伦精品1国产丝袜 | 亚洲国产精品一区二区美利坚 | 麻豆人妻少妇精品无码专区 | 天天拍夜夜添久久精品大 | 久久www免费人成人片 | 亚洲欧洲日本综合aⅴ在线 | 18精品久久久无码午夜福利 | 国产免费久久久久久无码 | 131美女爱做视频 | 中文字幕人成乱码熟女app | 免费无码午夜福利片69 | 欧美色就是色 | 久热国产vs视频在线观看 | 奇米影视888欧美在线观看 | 色婷婷香蕉在线一区二区 | 丰满少妇弄高潮了www | 国产精品多人p群无码 | 图片区 小说区 区 亚洲五月 | 国产乡下妇女做爰 | 午夜丰满少妇性开放视频 | 免费人成在线观看网站 | 狂野欧美性猛xxxx乱大交 | 九九综合va免费看 | 夜夜夜高潮夜夜爽夜夜爰爰 | 嫩b人妻精品一区二区三区 | 久久99久久99精品中文字幕 | 精品乱子伦一区二区三区 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 成 人影片 免费观看 | 乱人伦人妻中文字幕无码 | 久久久久成人片免费观看蜜芽 | 水蜜桃色314在线观看 | 一本色道婷婷久久欧美 | 久久精品99久久香蕉国产色戒 | 免费人成在线观看网站 | 男人扒开女人内裤强吻桶进去 | 少妇一晚三次一区二区三区 | 亚洲码国产精品高潮在线 | 好爽又高潮了毛片免费下载 | 女高中生第一次破苞av | 精品日本一区二区三区在线观看 | 露脸叫床粗话东北少妇 | 蜜臀av无码人妻精品 | 成人无码精品一区二区三区 | 国精产品一品二品国精品69xx | 久久这里只有精品视频9 | 久久久亚洲欧洲日产国码αv | 十八禁视频网站在线观看 | 爽爽影院免费观看 | 国产午夜手机精彩视频 | 久激情内射婷内射蜜桃人妖 | 欧美激情内射喷水高潮 | 国产成人综合美国十次 | 久久久av男人的天堂 | 色五月五月丁香亚洲综合网 | 久久精品99久久香蕉国产色戒 | 欧美日韩视频无码一区二区三 | 国产亚洲欧美日韩亚洲中文色 | 色诱久久久久综合网ywww | 特大黑人娇小亚洲女 | 久久久久se色偷偷亚洲精品av | 久久久国产一区二区三区 | 午夜性刺激在线视频免费 | 日本大香伊一区二区三区 | 无码精品人妻一区二区三区av | аⅴ资源天堂资源库在线 | 日日麻批免费40分钟无码 | 久久久久久久女国产乱让韩 | 中文字幕中文有码在线 | 欧美xxxxx精品 | 九九综合va免费看 | 麻豆精产国品 | 亚洲精品午夜国产va久久成人 | 亚洲日韩乱码中文无码蜜桃臀网站 | 亚洲中文字幕av在天堂 | 亚洲日韩中文字幕在线播放 | 九九久久精品国产免费看小说 | 国产一区二区不卡老阿姨 | 四十如虎的丰满熟妇啪啪 | 日本乱人伦片中文三区 | 97精品人妻一区二区三区香蕉 | 欧美大屁股xxxxhd黑色 | 免费看少妇作爱视频 | а√天堂www在线天堂小说 | 久久综合九色综合97网 | 日韩欧美群交p片內射中文 | 亚洲欧美综合区丁香五月小说 | 亲嘴扒胸摸屁股激烈网站 | 亚洲s码欧洲m码国产av | 国产一精品一av一免费 | 欧洲精品码一区二区三区免费看 | 性啪啪chinese东北女人 | 国产女主播喷水视频在线观看 | 无遮挡国产高潮视频免费观看 | 国产精品视频免费播放 | 日本精品人妻无码77777 天堂一区人妻无码 | 欧美激情综合亚洲一二区 | 亚洲色成人中文字幕网站 | 久久伊人色av天堂九九小黄鸭 | 高潮喷水的毛片 | 精品欧美一区二区三区久久久 | 狠狠躁日日躁夜夜躁2020 | 男女性色大片免费网站 | 久久国产36精品色熟妇 | 日本饥渴人妻欲求不满 | 日韩欧美成人免费观看 | 婷婷丁香五月天综合东京热 | 精品熟女少妇av免费观看 | 久久国产自偷自偷免费一区调 | 国产成人久久精品流白浆 | 欧美变态另类xxxx | 免费乱码人妻系列无码专区 | 中文字幕人妻丝袜二区 | 天天av天天av天天透 | 欧美人妻一区二区三区 | 六月丁香婷婷色狠狠久久 | 樱花草在线社区www | 天堂无码人妻精品一区二区三区 | 成人性做爰aaa片免费看 | 国产午夜亚洲精品不卡下载 | 十八禁视频网站在线观看 | 日本精品人妻无码免费大全 | 国产av剧情md精品麻豆 | 午夜免费福利小电影 | 亚洲综合另类小说色区 | 中文字幕无码人妻少妇免费 | 国产午夜手机精彩视频 | 亚洲国产av美女网站 | 中国大陆精品视频xxxx | 大肉大捧一进一出好爽视频 | 黄网在线观看免费网站 | 97色伦图片97综合影院 | 麻豆国产97在线 | 欧洲 | 色婷婷久久一区二区三区麻豆 | 无码人妻出轨黑人中文字幕 | 亚洲国产av美女网站 | 激情内射亚州一区二区三区爱妻 | 国内老熟妇对白xxxxhd | 精品国产福利一区二区 | 久久久久av无码免费网 | 天天躁夜夜躁狠狠是什么心态 | 性色av无码免费一区二区三区 | 久久无码专区国产精品s | 亚洲精品一区三区三区在线观看 | 无码人妻丰满熟妇区毛片18 | 欧美丰满熟妇xxxx性ppx人交 | 色情久久久av熟女人妻网站 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产无套粉嫩白浆在线 | 日日麻批免费40分钟无码 | 最近免费中文字幕中文高清百度 | 国产色视频一区二区三区 | 精品人妻av区 | 夜夜高潮次次欢爽av女 | 亚洲乱码国产乱码精品精 | 国产成人人人97超碰超爽8 | 四虎国产精品一区二区 | 青青青爽视频在线观看 | 中文字幕乱妇无码av在线 | 性色欲情网站iwww九文堂 | 中文字幕乱码人妻二区三区 | 国产精品毛多多水多 | 日产国产精品亚洲系列 | 亚洲理论电影在线观看 | 国产成人人人97超碰超爽8 | aⅴ在线视频男人的天堂 | 亚洲成色www久久网站 | 婷婷五月综合激情中文字幕 | 99麻豆久久久国产精品免费 | 国产色视频一区二区三区 | 熟妇人妻无乱码中文字幕 | 国产一区二区三区影院 | 伊人久久婷婷五月综合97色 | 成人动漫在线观看 | 老熟女重囗味hdxx69 | 中文字幕无码热在线视频 | 午夜精品久久久久久久 | 亚洲色欲久久久综合网东京热 | 永久黄网站色视频免费直播 | 国产精品美女久久久网av | 领导边摸边吃奶边做爽在线观看 | 人人澡人摸人人添 | 亚洲啪av永久无码精品放毛片 | 人妻有码中文字幕在线 | 久久99国产综合精品 | 无码人妻黑人中文字幕 | 午夜理论片yy44880影院 | 中文字幕av无码一区二区三区电影 | 精品人妻av区 | 日韩无码专区 | 帮老师解开蕾丝奶罩吸乳网站 | 欧美性生交活xxxxxdddd | 国产精品多人p群无码 | 精品偷自拍另类在线观看 | 熟女少妇在线视频播放 | 在线 国产 欧美 亚洲 天堂 | 野外少妇愉情中文字幕 | 天天做天天爱天天爽综合网 | 日本爽爽爽爽爽爽在线观看免 | 国产激情无码一区二区app | 亚洲精品中文字幕久久久久 | 丰满人妻一区二区三区免费视频 | 波多野结衣av一区二区全免费观看 | 亚洲精品国产a久久久久久 | 熟妇人妻无乱码中文字幕 | 亚洲日韩av一区二区三区四区 | 97久久精品无码一区二区 | 亚洲国精产品一二二线 | 7777奇米四色成人眼影 | 国产又爽又黄又刺激的视频 | 亚洲日韩精品欧美一区二区 | 最近的中文字幕在线看视频 | 日韩无码专区 | 丰满岳乱妇在线观看中字无码 | 久久国语露脸国产精品电影 | 最新版天堂资源中文官网 | ass日本丰满熟妇pics | 精品欧美一区二区三区久久久 | 精品人妻人人做人人爽 | 领导边摸边吃奶边做爽在线观看 | 国产真实伦对白全集 | 夜精品a片一区二区三区无码白浆 | 久久人人爽人人爽人人片ⅴ | 青草青草久热国产精品 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 欧美大屁股xxxxhd黑色 | 成熟女人特级毛片www免费 | 亚洲啪av永久无码精品放毛片 | 亚洲日本一区二区三区在线 | 日韩人妻少妇一区二区三区 | 国产熟妇另类久久久久 | 免费国产成人高清在线观看网站 | 亚洲熟妇色xxxxx亚洲 | 亚拍精品一区二区三区探花 | 亚洲精品午夜无码电影网 | 2020最新国产自产精品 | 麻豆国产丝袜白领秘书在线观看 | 无码人妻丰满熟妇区毛片18 | 精品亚洲韩国一区二区三区 | 99久久久无码国产精品免费 | 欧洲vodafone精品性 | 国产精品成人av在线观看 | 四虎4hu永久免费 | 欧美人与禽猛交狂配 | 久久久久av无码免费网 | 亚洲 激情 小说 另类 欧美 | 无套内谢的新婚少妇国语播放 | 日本爽爽爽爽爽爽在线观看免 | 精品国产一区二区三区av 性色 | 野狼第一精品社区 | 国产明星裸体无码xxxx视频 | 天天拍夜夜添久久精品大 | 三级4级全黄60分钟 | 色诱久久久久综合网ywww | 一二三四在线观看免费视频 | 午夜无码区在线观看 | 红桃av一区二区三区在线无码av | 亚洲国产精品无码一区二区三区 | 极品嫩模高潮叫床 | 东京热一精品无码av | 色综合久久久无码网中文 | 一个人免费观看的www视频 | 无码国模国产在线观看 | 欧美真人作爱免费视频 | 色综合视频一区二区三区 | 久久人人97超碰a片精品 | 国产乱人无码伦av在线a | 少妇人妻大乳在线视频 | 国产精品理论片在线观看 | 人妻人人添人妻人人爱 | 大肉大捧一进一出好爽视频 | 在线亚洲高清揄拍自拍一品区 | 亚洲码国产精品高潮在线 | 亚洲综合伊人久久大杳蕉 | 亚洲精品成a人在线观看 | 久久精品国产99精品亚洲 | 精品夜夜澡人妻无码av蜜桃 | 国内精品久久久久久中文字幕 | 国产性生大片免费观看性 | 免费观看黄网站 | 欧美性色19p | 国产欧美精品一区二区三区 | 亚洲日韩一区二区 | 亚洲精品综合一区二区三区在线 | 亚洲一区二区三区偷拍女厕 | 特级做a爰片毛片免费69 | 国产国产精品人在线视 | 天堂а√在线中文在线 | 国产熟女一区二区三区四区五区 | 国产国语老龄妇女a片 | 成人片黄网站色大片免费观看 | 无码一区二区三区在线观看 | 3d动漫精品啪啪一区二区中 | 亚洲色欲色欲天天天www | 无码av免费一区二区三区试看 | 亚洲色欲久久久综合网东京热 | 中文字幕人成乱码熟女app | 婷婷丁香六月激情综合啪 | 黑人巨大精品欧美一区二区 | 国产精品国产三级国产专播 | 国产婷婷色一区二区三区在线 | 欧美精品国产综合久久 | 国内综合精品午夜久久资源 | 亚洲gv猛男gv无码男同 | 日韩欧美中文字幕在线三区 | 国产又粗又硬又大爽黄老大爷视 | 在线成人www免费观看视频 | 亚洲第一无码av无码专区 | 精品无人国产偷自产在线 | 天堂久久天堂av色综合 | 中文字幕乱码中文乱码51精品 | 日韩精品无码一本二本三本色 | 亚洲精品午夜无码电影网 | 婷婷五月综合缴情在线视频 | 性色欲网站人妻丰满中文久久不卡 | 国产特级毛片aaaaaaa高清 | 久久精品国产精品国产精品污 | 国产成人综合色在线观看网站 | 国产真人无遮挡作爱免费视频 | 成人无码精品一区二区三区 | 久精品国产欧美亚洲色aⅴ大片 | 欧美黑人乱大交 | 丝袜人妻一区二区三区 | www一区二区www免费 | 99久久精品无码一区二区毛片 | 天天摸天天碰天天添 | 无码帝国www无码专区色综合 | 中文精品久久久久人妻不卡 | 久热国产vs视频在线观看 | 天干天干啦夜天干天2017 | 六十路熟妇乱子伦 | 在教室伦流澡到高潮hnp视频 | 久久久亚洲欧洲日产国码αv | 小sao货水好多真紧h无码视频 | 日韩精品a片一区二区三区妖精 | 精品欧美一区二区三区久久久 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 精品国产乱码久久久久乱码 | 久久人人爽人人人人片 | av无码久久久久不卡免费网站 | 国产又爽又黄又刺激的视频 | 久久精品国产亚洲精品 | 亚洲欧美日韩成人高清在线一区 | 成 人 网 站国产免费观看 | 在线 国产 欧美 亚洲 天堂 | 精品久久久无码中文字幕 | 成人影院yy111111在线观看 | 国产极品视觉盛宴 | 国产成人亚洲综合无码 | 任你躁在线精品免费 | 国产精品亚洲综合色区韩国 | 国产av剧情md精品麻豆 | 国产人妻精品一区二区三区 | 亚洲综合另类小说色区 | 一本色道久久综合亚洲精品不卡 | 久久人人爽人人爽人人片av高清 | 欧美丰满老熟妇xxxxx性 | 国产精品国产三级国产专播 | 奇米影视888欧美在线观看 | 亚洲精品久久久久久一区二区 | 少妇性荡欲午夜性开放视频剧场 | 亚洲中文无码av永久不收费 | 未满成年国产在线观看 | 永久免费观看美女裸体的网站 | 日日摸夜夜摸狠狠摸婷婷 | 久久精品人人做人人综合 | 亚洲区小说区激情区图片区 | 久久国产精品二国产精品 | 97人妻精品一区二区三区 | 国产日产欧产精品精品app | 精品乱子伦一区二区三区 | 激情五月综合色婷婷一区二区 | 狂野欧美性猛xxxx乱大交 | 亚洲精品一区二区三区四区五区 | 人人妻人人澡人人爽欧美精品 | 麻豆蜜桃av蜜臀av色欲av | 成人无码视频免费播放 | 国产特级毛片aaaaaa高潮流水 | 欧美性生交活xxxxxdddd | 欧美 日韩 亚洲 在线 | 成人无码精品1区2区3区免费看 | 国产超碰人人爽人人做人人添 | 波多野结衣乳巨码无在线观看 | 亚洲色偷偷男人的天堂 | 久久综合九色综合97网 | 亚洲精品综合五月久久小说 | 日本又色又爽又黄的a片18禁 | 国产午夜视频在线观看 | 亚洲熟女一区二区三区 | аⅴ资源天堂资源库在线 | 国产三级精品三级男人的天堂 | 亚洲精品一区三区三区在线观看 | 日韩精品无码一本二本三本色 | 内射爽无广熟女亚洲 | 大肉大捧一进一出视频出来呀 | 天天躁夜夜躁狠狠是什么心态 | 老头边吃奶边弄进去呻吟 | 亚洲最大成人网站 | 亚洲综合无码一区二区三区 | 性色av无码免费一区二区三区 | 美女毛片一区二区三区四区 | 图片小说视频一区二区 | 亚洲乱码日产精品bd | 日日鲁鲁鲁夜夜爽爽狠狠 | 色欲人妻aaaaaaa无码 | 丰满少妇弄高潮了www | 激情国产av做激情国产爱 | 中文字幕av无码一区二区三区电影 | 欧美freesex黑人又粗又大 | 国产精品美女久久久久av爽李琼 | 亚洲阿v天堂在线 | 亚洲成av人片在线观看无码不卡 | 97精品人妻一区二区三区香蕉 | 国产精品无码永久免费888 | 久久精品国产大片免费观看 | 亚洲色成人中文字幕网站 | 国产精品va在线播放 | 精品国产一区二区三区四区 | 欧美黑人性暴力猛交喷水 | 色一情一乱一伦 | 国产精品嫩草久久久久 | 日本免费一区二区三区最新 | 亚洲人成网站色7799 | 人人妻人人澡人人爽人人精品浪潮 | 久久精品国产精品国产精品污 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 亚洲欧美综合区丁香五月小说 | 精品无码一区二区三区的天堂 | 波多野结衣av一区二区全免费观看 | 丰满少妇弄高潮了www | 色欲av亚洲一区无码少妇 | 精品人妻人人做人人爽夜夜爽 | 成人免费视频视频在线观看 免费 | 久久久久国色av免费观看性色 | 国内综合精品午夜久久资源 | 亚洲阿v天堂在线 | 在线观看国产一区二区三区 | 国产成人无码av片在线观看不卡 | 丝袜美腿亚洲一区二区 | 精品久久久久久亚洲精品 | 一本久久a久久精品亚洲 | 欧美黑人巨大xxxxx | 日本一本二本三区免费 | 亚洲中文字幕在线无码一区二区 | 欧美三级a做爰在线观看 | 精品人人妻人人澡人人爽人人 | 人妻夜夜爽天天爽三区 | 国产成人精品优优av | 久久婷婷五月综合色国产香蕉 | 一本大道久久东京热无码av | 国产特级毛片aaaaaa高潮流水 | 4hu四虎永久在线观看 | 在线观看免费人成视频 | 亚洲精品久久久久avwww潮水 | 牲欲强的熟妇农村老妇女视频 | 色综合久久久无码中文字幕 | 亚洲国产精华液网站w | 亚洲日韩精品欧美一区二区 | 国语自产偷拍精品视频偷 | 99久久精品无码一区二区毛片 | 强辱丰满人妻hd中文字幕 | 国产熟妇高潮叫床视频播放 | 国产av无码专区亚洲a∨毛片 | 免费观看激色视频网站 | 久久久中文字幕日本无吗 | 天干天干啦夜天干天2017 | 成人精品视频一区二区 | ass日本丰满熟妇pics | 亚洲自偷自拍另类第1页 | 国产精品18久久久久久麻辣 | 青青草原综合久久大伊人精品 | 国产一区二区三区精品视频 | 成 人 网 站国产免费观看 | 77777熟女视频在线观看 а天堂中文在线官网 | 日本乱偷人妻中文字幕 | 内射老妇bbwx0c0ck | 小鲜肉自慰网站xnxx | 久久精品一区二区三区四区 | 综合网日日天干夜夜久久 | 成在人线av无码免观看麻豆 | 国产成人精品必看 | 亚洲精品国产第一综合99久久 | 无码人妻黑人中文字幕 | 双乳奶水饱满少妇呻吟 | 国产成人精品三级麻豆 | 亚洲aⅴ无码成人网站国产app | 日韩人妻无码中文字幕视频 | 亚洲精品国产精品乱码视色 | 精品无人区无码乱码毛片国产 | 久青草影院在线观看国产 | 国产熟女一区二区三区四区五区 | 亚洲欧美精品伊人久久 | 成人欧美一区二区三区黑人 | 国产亚洲精品久久久久久国模美 | 午夜福利试看120秒体验区 | 夜夜躁日日躁狠狠久久av | 亚洲色欲色欲天天天www | 国产又爽又猛又粗的视频a片 | 日韩 欧美 动漫 国产 制服 | 国产人妖乱国产精品人妖 | 国产成人亚洲综合无码 | 国产精品美女久久久久av爽李琼 | 欧美丰满老熟妇xxxxx性 | 97夜夜澡人人爽人人喊中国片 | 国产成人无码专区 | 婷婷丁香六月激情综合啪 | 大地资源网第二页免费观看 | 野外少妇愉情中文字幕 | 国产人妖乱国产精品人妖 | 乌克兰少妇xxxx做受 | 日日噜噜噜噜夜夜爽亚洲精品 | 国产精品毛多多水多 | 亚洲国产精品久久人人爱 | 欧美肥老太牲交大战 | 久久久久免费看成人影片 | 免费播放一区二区三区 | 亚洲色欲色欲欲www在线 | 中文字幕无码热在线视频 | 久久国产精品萌白酱免费 | 又大又黄又粗又爽的免费视频 | 妺妺窝人体色www在线小说 | 99久久亚洲精品无码毛片 | 日本免费一区二区三区最新 | 亚洲欧洲日本无在线码 | 99riav国产精品视频 | 国内综合精品午夜久久资源 | 性做久久久久久久免费看 | 亚洲熟悉妇女xxx妇女av | 国产卡一卡二卡三 | 亚洲欧洲日本无在线码 | 日本一卡二卡不卡视频查询 | 99国产欧美久久久精品 | 四虎影视成人永久免费观看视频 | 色综合视频一区二区三区 | 国产精品99久久精品爆乳 | 国产精品毛片一区二区 | 国产一区二区三区影院 | 日韩欧美中文字幕在线三区 | 免费看少妇作爱视频 | 亚洲熟妇自偷自拍另类 | 一二三四社区在线中文视频 | 午夜免费福利小电影 | 东京热一精品无码av | 亚洲成av人片天堂网无码】 | 无码人妻黑人中文字幕 | 国产精品久久久午夜夜伦鲁鲁 | 午夜精品久久久久久久 | 亚洲精品成a人在线观看 | 国产精品亚洲五月天高清 | 东京热无码av男人的天堂 | 对白脏话肉麻粗话av | 欧洲精品码一区二区三区免费看 | 强奷人妻日本中文字幕 | 国产精品久久久久久无码 | 99国产精品白浆在线观看免费 | 麻豆国产丝袜白领秘书在线观看 | 色婷婷综合中文久久一本 | 久久精品国产精品国产精品污 | 老司机亚洲精品影院 | 日韩精品无码一本二本三本色 | 中文字幕av日韩精品一区二区 | 成人免费视频视频在线观看 免费 | 中文字幕日韩精品一区二区三区 | 人人妻人人澡人人爽精品欧美 | 成人片黄网站色大片免费观看 | 亚洲另类伦春色综合小说 | 亚洲日韩一区二区三区 | 国产网红无码精品视频 | 人人澡人人透人人爽 | 欧美日韩在线亚洲综合国产人 | 无码人妻精品一区二区三区不卡 | 婷婷六月久久综合丁香 | 国精品人妻无码一区二区三区蜜柚 | 国产美女极度色诱视频www | 美女毛片一区二区三区四区 | 永久免费精品精品永久-夜色 | 熟妇人妻中文av无码 | 天天做天天爱天天爽综合网 | 少妇太爽了在线观看 | 亚欧洲精品在线视频免费观看 | 台湾无码一区二区 | 久久人人97超碰a片精品 | 免费观看的无遮挡av | 老熟女重囗味hdxx69 | 啦啦啦www在线观看免费视频 | 欧美丰满老熟妇xxxxx性 | 亚洲欧美综合区丁香五月小说 | 国产成人亚洲综合无码 | 日本精品人妻无码77777 天堂一区人妻无码 | 4hu四虎永久在线观看 | 天天摸天天透天天添 | 亚洲毛片av日韩av无码 | 老子影院午夜伦不卡 | 少妇邻居内射在线 | 日韩人妻无码中文字幕视频 | 国产亲子乱弄免费视频 | 99久久精品午夜一区二区 | 国产激情无码一区二区 | 欧美三级不卡在线观看 | 搡女人真爽免费视频大全 | 亚洲国产精华液网站w | 成年美女黄网站色大免费全看 | 最近的中文字幕在线看视频 | 亚洲午夜久久久影院 | 性色欲网站人妻丰满中文久久不卡 | 18无码粉嫩小泬无套在线观看 | 国产猛烈高潮尖叫视频免费 | 亚洲啪av永久无码精品放毛片 | 精品久久久久久亚洲精品 | 一个人免费观看的www视频 | 成人aaa片一区国产精品 | 国产99久久精品一区二区 | 国产人妻久久精品二区三区老狼 | 亚洲狠狠婷婷综合久久 | 荫蒂被男人添的好舒服爽免费视频 | 给我免费的视频在线观看 | 亚洲精品久久久久久一区二区 | 精品乱子伦一区二区三区 | 精品人妻人人做人人爽夜夜爽 | 国产人妻精品午夜福利免费 | 日本精品人妻无码77777 天堂一区人妻无码 | 日本熟妇大屁股人妻 | 国产成人精品无码播放 | 波多野结衣高清一区二区三区 | 国产真实乱对白精彩久久 | 丰满妇女强制高潮18xxxx | 麻豆果冻传媒2021精品传媒一区下载 | 人妻少妇精品久久 | 久久久久国色av免费观看性色 | 天堂亚洲免费视频 | 免费观看激色视频网站 | 97久久国产亚洲精品超碰热 | 国产三级精品三级男人的天堂 | 精品人人妻人人澡人人爽人人 | 欧美成人高清在线播放 | 精品无码国产一区二区三区av | 日本丰满护士爆乳xxxx | 婷婷丁香六月激情综合啪 | 狠狠亚洲超碰狼人久久 | 国产精品va在线观看无码 | 亚洲 日韩 欧美 成人 在线观看 | 亚洲国产欧美国产综合一区 | 中文字幕乱妇无码av在线 | 丝袜美腿亚洲一区二区 | 欧美乱妇无乱码大黄a片 | 国产免费无码一区二区视频 | 亚洲精品国产第一综合99久久 | 永久黄网站色视频免费直播 | 成人精品一区二区三区中文字幕 | 图片区 小说区 区 亚洲五月 | 少妇性荡欲午夜性开放视频剧场 | 一本大道久久东京热无码av | 2020久久香蕉国产线看观看 | 亚洲国产精品久久久久久 | 天天躁日日躁狠狠躁免费麻豆 | 最新版天堂资源中文官网 | 97久久超碰中文字幕 | 给我免费的视频在线观看 | 久久精品人妻少妇一区二区三区 | 东京热一精品无码av | 国产三级久久久精品麻豆三级 | 曰韩少妇内射免费播放 | 无码国产色欲xxxxx视频 | 国产特级毛片aaaaaaa高清 | 少女韩国电视剧在线观看完整 | 丝袜人妻一区二区三区 | 免费看男女做好爽好硬视频 | 丰满人妻翻云覆雨呻吟视频 | 国产莉萝无码av在线播放 | 精品人妻中文字幕有码在线 | 国产高清不卡无码视频 | 国语自产偷拍精品视频偷 | 日产精品高潮呻吟av久久 | 色婷婷av一区二区三区之红樱桃 | 中文字幕无码免费久久9一区9 | 亚洲熟悉妇女xxx妇女av | 黑人巨大精品欧美一区二区 | 日本欧美一区二区三区乱码 | 亚洲精品中文字幕久久久久 | 男人扒开女人内裤强吻桶进去 | 无码毛片视频一区二区本码 | 色 综合 欧美 亚洲 国产 | 蜜臀av无码人妻精品 | 欧美人与牲动交xxxx | 国产欧美精品一区二区三区 | 久久久av男人的天堂 | 亚洲午夜久久久影院 | 国产精品久久久av久久久 | 国产又粗又硬又大爽黄老大爷视 | 色综合久久久久综合一本到桃花网 | 一本久久a久久精品亚洲 | 成人无码影片精品久久久 | 国产精品亚洲五月天高清 | 色老头在线一区二区三区 | 波多野结衣aⅴ在线 | 精品无码国产自产拍在线观看蜜 | 国产超级va在线观看视频 | 男女爱爱好爽视频免费看 | 欧美熟妇另类久久久久久不卡 | 成人欧美一区二区三区黑人免费 | 麻豆国产97在线 | 欧洲 | 欧美黑人乱大交 | 亚洲精品欧美二区三区中文字幕 | 午夜熟女插插xx免费视频 | 亚洲综合无码久久精品综合 | 国产精品理论片在线观看 | 纯爱无遮挡h肉动漫在线播放 | 亚洲国产高清在线观看视频 | 综合人妻久久一区二区精品 | 国产麻豆精品精东影业av网站 | 任你躁国产自任一区二区三区 | 日本精品久久久久中文字幕 | 奇米影视7777久久精品人人爽 | 中文字幕人成乱码熟女app | 乱人伦人妻中文字幕无码久久网 | 高潮毛片无遮挡高清免费 | 亚洲中文字幕在线无码一区二区 | 亚洲七七久久桃花影院 | 久久人妻内射无码一区三区 | 国产午夜亚洲精品不卡下载 | 日日摸日日碰夜夜爽av | 日本一区二区三区免费播放 | 亚洲成av人综合在线观看 | 久久久久久久人妻无码中文字幕爆 | 亲嘴扒胸摸屁股激烈网站 | 荫蒂被男人添的好舒服爽免费视频 | 欧美激情综合亚洲一二区 | 亚洲成在人网站无码天堂 | 亚洲精品国产精品乱码不卡 | 国产精品久久久久久久9999 | 亚洲男人av天堂午夜在 | 波多野结衣乳巨码无在线观看 | 日本熟妇乱子伦xxxx | 国语精品一区二区三区 | 任你躁在线精品免费 | 永久免费观看国产裸体美女 | 国产69精品久久久久app下载 | 国产肉丝袜在线观看 | 国产一区二区三区四区五区加勒比 | 久久99精品国产.久久久久 | 亚洲毛片av日韩av无码 | 亚洲国产午夜精品理论片 | 色偷偷人人澡人人爽人人模 | 国精产品一区二区三区 | 成人精品天堂一区二区三区 | 人人超人人超碰超国产 | 装睡被陌生人摸出水好爽 | 无遮无挡爽爽免费视频 | 久久久亚洲欧洲日产国码αv | 国产精品办公室沙发 | 女人色极品影院 | 国产做国产爱免费视频 | 水蜜桃亚洲一二三四在线 | 中文字幕乱码中文乱码51精品 | 成 人 网 站国产免费观看 | av无码电影一区二区三区 | 国产精品成人av在线观看 | 牲交欧美兽交欧美 | 欧美第一黄网免费网站 | 欧美自拍另类欧美综合图片区 | 亚洲综合久久一区二区 | 亚洲熟妇色xxxxx欧美老妇y | 色欲人妻aaaaaaa无码 | 日日碰狠狠躁久久躁蜜桃 | 一本无码人妻在中文字幕免费 | 久久亚洲国产成人精品性色 | 男人扒开女人内裤强吻桶进去 | 久久久久久久人妻无码中文字幕爆 | 中文字幕 亚洲精品 第1页 | 无码吃奶揉捏奶头高潮视频 | 国产热a欧美热a在线视频 | 特黄特色大片免费播放器图片 | 日韩人妻无码中文字幕视频 | 亚洲成av人片天堂网无码】 | 久久久精品人妻久久影视 | 亚洲日本在线电影 | 人人澡人摸人人添 | 女人被男人爽到呻吟的视频 | 亚洲国产成人av在线观看 | 亚洲人成影院在线无码按摩店 | 人妻aⅴ无码一区二区三区 | 亚洲の无码国产の无码步美 | 宝宝好涨水快流出来免费视频 | 精品无人区无码乱码毛片国产 | 少妇愉情理伦片bd | 精品偷拍一区二区三区在线看 | 天天躁夜夜躁狠狠是什么心态 | 亚洲一区二区三区播放 | 欧美 日韩 亚洲 在线 | 国产综合色产在线精品 | 国产成人无码午夜视频在线观看 | 啦啦啦www在线观看免费视频 | 中文字幕无码av波多野吉衣 | 精品久久综合1区2区3区激情 | √天堂中文官网8在线 | 久久久久久久人妻无码中文字幕爆 | 亚洲精品一区二区三区在线 | 中文字幕中文有码在线 | 国模大胆一区二区三区 | 在线播放免费人成毛片乱码 | 亚洲毛片av日韩av无码 | 日韩在线不卡免费视频一区 | 女人被男人躁得好爽免费视频 | 黑森林福利视频导航 | 欧美亚洲日韩国产人成在线播放 | 国产黄在线观看免费观看不卡 | 激情五月综合色婷婷一区二区 | 人人澡人人透人人爽 | 国产在线精品一区二区高清不卡 | 欧美 日韩 人妻 高清 中文 | 中文无码伦av中文字幕 | 5858s亚洲色大成网站www | 国产亚洲精品久久久久久 | 狠狠色色综合网站 | av香港经典三级级 在线 | 亚洲 另类 在线 欧美 制服 | 亚洲性无码av中文字幕 | 国产农村乱对白刺激视频 | 97久久精品无码一区二区 | 久久久久久亚洲精品a片成人 | 国产手机在线αⅴ片无码观看 | 熟妇激情内射com | 鲁大师影院在线观看 | 日产精品99久久久久久 | 香港三级日本三级妇三级 | 性开放的女人aaa片 | 国内精品人妻无码久久久影院蜜桃 | 国产欧美精品一区二区三区 | 黑人巨大精品欧美黑寡妇 | 领导边摸边吃奶边做爽在线观看 | 无码福利日韩神码福利片 | 成年美女黄网站色大免费全看 | 丰腴饱满的极品熟妇 | 国产97人人超碰caoprom | 国产肉丝袜在线观看 | 国产 浪潮av性色四虎 | a在线观看免费网站大全 | 中文字幕无码人妻少妇免费 | 97无码免费人妻超级碰碰夜夜 | 国产精品办公室沙发 | 国产午夜无码视频在线观看 | 精品国精品国产自在久国产87 | 18禁止看的免费污网站 | 麻豆国产97在线 | 欧洲 | 伊人色综合久久天天小片 | 国产特级毛片aaaaaa高潮流水 | 精品久久久无码中文字幕 | 国产欧美精品一区二区三区 | 东北女人啪啪对白 | 99久久久无码国产精品免费 | 日本www一道久久久免费榴莲 | 精品国产一区二区三区四区 | 欧美丰满少妇xxxx性 | www国产亚洲精品久久久日本 | 97无码免费人妻超级碰碰夜夜 | 亚洲欧洲无卡二区视頻 | 少妇无码av无码专区在线观看 | 国产成人无码av一区二区 | 精品国产一区二区三区四区在线看 | 国产精品亚洲综合色区韩国 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 中文字幕人妻无码一夲道 | 人妻夜夜爽天天爽三区 | 亚洲中文字幕久久无码 | 精品国产一区二区三区四区 | 精品欧洲av无码一区二区三区 | 中文字幕+乱码+中文字幕一区 | 亚洲精品中文字幕久久久久 | 高清不卡一区二区三区 | 亚洲欧洲日本综合aⅴ在线 | 丰满少妇女裸体bbw | 国产亚洲欧美日韩亚洲中文色 | 色综合久久88色综合天天 | 国产av无码专区亚洲a∨毛片 | 东京无码熟妇人妻av在线网址 | 老司机亚洲精品影院 | 亚洲色欲色欲天天天www | 一本加勒比波多野结衣 | 无码福利日韩神码福利片 | 鲁鲁鲁爽爽爽在线视频观看 | 色婷婷综合中文久久一本 | 国产精品对白交换视频 | 中文字幕人妻丝袜二区 | 天天做天天爱天天爽综合网 | 在线观看欧美一区二区三区 | 色婷婷综合激情综在线播放 | 中文字幕人妻无码一区二区三区 | 熟妇激情内射com | 久久精品国产亚洲精品 | 88国产精品欧美一区二区三区 | 精品无码一区二区三区爱欲 | 日本熟妇大屁股人妻 | 国产亚洲人成在线播放 | 国产成人无码专区 | 国产亚洲日韩欧美另类第八页 | 亚洲一区二区三区香蕉 | 在教室伦流澡到高潮hnp视频 | 久久久久久av无码免费看大片 | 西西人体www44rt大胆高清 | 国产真人无遮挡作爱免费视频 | 国产激情一区二区三区 | 18精品久久久无码午夜福利 | 国产在线aaa片一区二区99 | 国产亚洲精品久久久久久国模美 | 亚洲国产精品久久人人爱 | 在线亚洲高清揄拍自拍一品区 | 中文字幕无码热在线视频 | 黄网在线观看免费网站 | 国产精品毛片一区二区 | 国产精品99久久精品爆乳 | 天堂无码人妻精品一区二区三区 | 久久人妻内射无码一区三区 | 学生妹亚洲一区二区 | 国产成人无码a区在线观看视频app | 色窝窝无码一区二区三区色欲 | 亚洲成a人片在线观看日本 | 中文无码伦av中文字幕 | 色一情一乱一伦一区二区三欧美 | 久久久久亚洲精品中文字幕 | 日本熟妇人妻xxxxx人hd | 国产亚洲精品久久久久久久 | av无码电影一区二区三区 | 久久亚洲中文字幕精品一区 | 波多野42部无码喷潮在线 | 精品久久久中文字幕人妻 | 欧美国产日产一区二区 | 国产精品久久久久无码av色戒 | 国产另类ts人妖一区二区 | 亚洲国产精华液网站w | 精品人妻人人做人人爽夜夜爽 | 欧美 丝袜 自拍 制服 另类 | 亚洲码国产精品高潮在线 | 国产av一区二区三区最新精品 | 亚洲熟熟妇xxxx | 中文字幕无码av波多野吉衣 | 国产精品自产拍在线观看 | 女高中生第一次破苞av | 99在线 | 亚洲 | 黑人巨大精品欧美一区二区 | 无套内谢老熟女 | 久久久久久av无码免费看大片 | 国产偷抇久久精品a片69 | 国产内射爽爽大片视频社区在线 | 国产精品久久久午夜夜伦鲁鲁 | 日韩人妻少妇一区二区三区 | 欧美xxxxx精品 | 国产激情一区二区三区 | 国产精品igao视频网 | 久久久久99精品成人片 | 久久亚洲精品中文字幕无男同 | 国产尤物精品视频 | 啦啦啦www在线观看免费视频 | 亚洲色偷偷偷综合网 | 熟女俱乐部五十路六十路av | 中文字幕无码热在线视频 | 午夜精品久久久久久久久 | 亚洲一区二区三区偷拍女厕 | 亚洲中文字幕在线无码一区二区 | 久久久中文字幕日本无吗 | 国精品人妻无码一区二区三区蜜柚 | 国精产品一品二品国精品69xx | 300部国产真实乱 | 成人女人看片免费视频放人 | 伊人久久大香线蕉av一区二区 | 无码国模国产在线观看 | 国产午夜无码视频在线观看 | 久久精品国产一区二区三区 | 精品欧洲av无码一区二区三区 | 中文字幕 亚洲精品 第1页 | 国产精品久久久久久久影院 | www国产亚洲精品久久网站 | 天堂а√在线中文在线 | 两性色午夜视频免费播放 | 日本在线高清不卡免费播放 | 久久无码中文字幕免费影院蜜桃 | 国产精品久久福利网站 | 亚洲精品鲁一鲁一区二区三区 | 日韩亚洲欧美中文高清在线 | 好爽又高潮了毛片免费下载 | 国产偷抇久久精品a片69 | 日欧一片内射va在线影院 | 色婷婷综合激情综在线播放 | √天堂资源地址中文在线 | 粉嫩少妇内射浓精videos | 欧洲vodafone精品性 | 一个人免费观看的www视频 | 国产一区二区三区影院 | 天天摸天天碰天天添 | 露脸叫床粗话东北少妇 | 麻豆果冻传媒2021精品传媒一区下载 | 台湾无码一区二区 | 97久久精品无码一区二区 | 1000部啪啪未满十八勿入下载 | 一本精品99久久精品77 | 精品国产青草久久久久福利 | 无码毛片视频一区二区本码 | 欧美日韩在线亚洲综合国产人 | 国产电影无码午夜在线播放 | 日韩精品成人一区二区三区 | 欧美一区二区三区视频在线观看 | 人人爽人人澡人人人妻 | 欧美xxxxx精品 | 午夜精品久久久内射近拍高清 | 国产精品人人爽人人做我的可爱 | 扒开双腿吃奶呻吟做受视频 | 久久综合激激的五月天 | 国内精品久久久久久中文字幕 | 久久国产36精品色熟妇 | 国产精品va在线播放 | 国产免费观看黄av片 | 综合人妻久久一区二区精品 | 国产超碰人人爽人人做人人添 | 国内少妇偷人精品视频免费 | 黑人玩弄人妻中文在线 | 亚洲日韩av一区二区三区四区 | 欧美黑人性暴力猛交喷水 | 熟妇人妻无码xxx视频 | 亚洲精品久久久久中文第一幕 | 欧美性黑人极品hd | 久精品国产欧美亚洲色aⅴ大片 | 亚洲 欧美 激情 小说 另类 | 国产国产精品人在线视 | 亚洲一区二区三区在线观看网站 | 中文字幕乱码人妻二区三区 | 国产成人精品久久亚洲高清不卡 | 国产热a欧美热a在线视频 | aⅴ亚洲 日韩 色 图网站 播放 | 无码人妻精品一区二区三区下载 | 亚洲国产精品一区二区美利坚 | 欧美丰满熟妇xxxx性ppx人交 | 国产特级毛片aaaaaaa高清 | 呦交小u女精品视频 | 亚洲国产精品久久久久久 | 中文字幕无码视频专区 | 日韩精品久久久肉伦网站 | 亚洲成a人片在线观看无码3d | 国产亚洲欧美在线专区 | 无码精品国产va在线观看dvd | 欧美日韩亚洲国产精品 | 欧美老妇与禽交 | 国产在线精品一区二区高清不卡 | 牲欲强的熟妇农村老妇女 | 5858s亚洲色大成网站www | 国产精品无码久久av | 欧美野外疯狂做受xxxx高潮 | 成人毛片一区二区 | 亚无码乱人伦一区二区 | 亚洲人成影院在线观看 | 99riav国产精品视频 | 国产精品久久国产精品99 | 少女韩国电视剧在线观看完整 | 美女扒开屁股让男人桶 | 天天躁日日躁狠狠躁免费麻豆 | 98国产精品综合一区二区三区 | 无码成人精品区在线观看 | 熟女体下毛毛黑森林 | 精品欧洲av无码一区二区三区 | 性欧美videos高清精品 | 午夜福利不卡在线视频 | 欧美肥老太牲交大战 | 亚洲s色大片在线观看 | 一本大道伊人av久久综合 | 国精产品一品二品国精品69xx | 亚洲成av人综合在线观看 | 成人无码精品1区2区3区免费看 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 亚洲理论电影在线观看 | 老熟妇乱子伦牲交视频 | 亚洲一区二区观看播放 | 婷婷丁香五月天综合东京热 | 日本一区二区三区免费播放 | 久久综合激激的五月天 | 亚洲精品鲁一鲁一区二区三区 | 成人性做爰aaa片免费看不忠 | 狂野欧美性猛交免费视频 | 人妻少妇精品视频专区 | 性色欲情网站iwww九文堂 | 熟女少妇在线视频播放 | 人妻少妇精品无码专区二区 | 亚洲中文字幕在线无码一区二区 | 乌克兰少妇性做爰 | 中文字幕人妻无码一夲道 | 乱人伦中文视频在线观看 | 内射欧美老妇wbb | 日本精品久久久久中文字幕 | 2020久久香蕉国产线看观看 | 妺妺窝人体色www在线小说 | 亚洲精品一区国产 | 久久无码人妻影院 | 精品国产青草久久久久福利 | 国产成人无码区免费内射一片色欲 | 人人爽人人澡人人高潮 | 夜精品a片一区二区三区无码白浆 | 久久久久亚洲精品男人的天堂 | 国产亚洲精品精品国产亚洲综合 | 狠狠亚洲超碰狼人久久 | 2020久久香蕉国产线看观看 | 国产成人无码午夜视频在线观看 | 18精品久久久无码午夜福利 | 久久99国产综合精品 | 99麻豆久久久国产精品免费 | 中文久久乱码一区二区 | 亚洲日韩乱码中文无码蜜桃臀网站 | 永久免费观看国产裸体美女 | 高中生自慰www网站 | 国产精品久久久av久久久 | 偷窥日本少妇撒尿chinese | 双乳奶水饱满少妇呻吟 | 中文字幕日韩精品一区二区三区 | 国产农村妇女高潮大叫 | 婷婷五月综合激情中文字幕 | 性做久久久久久久久 | 久久精品国产99久久6动漫 | 自拍偷自拍亚洲精品10p | 精品成在人线av无码免费看 | 九九久久精品国产免费看小说 | 人人妻人人澡人人爽人人精品 | 国产精品久久久久久亚洲影视内衣 | 国产激情艳情在线看视频 | 成人影院yy111111在线观看 | 亚洲 日韩 欧美 成人 在线观看 | 亚洲成a人片在线观看日本 | 亚洲中文字幕va福利 | 欧美成人高清在线播放 | 亚洲国产成人av在线观看 | 大肉大捧一进一出视频出来呀 | 国产av无码专区亚洲awww | 欧美激情一区二区三区成人 | 激情内射亚州一区二区三区爱妻 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 亚洲性无码av中文字幕 | 国产艳妇av在线观看果冻传媒 | 男人的天堂2018无码 | 色综合久久久无码网中文 | 亚洲成a人片在线观看无码3d | 小泽玛莉亚一区二区视频在线 | 乱中年女人伦av三区 | 在线成人www免费观看视频 | 亚洲精品一区三区三区在线观看 | 人妻少妇精品无码专区二区 | 丰满少妇弄高潮了www | 99久久亚洲精品无码毛片 | 亲嘴扒胸摸屁股激烈网站 | 欧美阿v高清资源不卡在线播放 | 99麻豆久久久国产精品免费 | 少女韩国电视剧在线观看完整 | 免费观看的无遮挡av | 日日碰狠狠躁久久躁蜜桃 | 无码国产色欲xxxxx视频 | 国产疯狂伦交大片 | 欧美人与禽猛交狂配 | 国产网红无码精品视频 | 51国偷自产一区二区三区 | 免费人成网站视频在线观看 | 无码福利日韩神码福利片 | 国产午夜福利100集发布 | 一个人看的www免费视频在线观看 | 日韩亚洲欧美中文高清在线 | 乱码av麻豆丝袜熟女系列 | 国产色视频一区二区三区 | 国产激情一区二区三区 | 久久久www成人免费毛片 | 色综合久久中文娱乐网 | 国产明星裸体无码xxxx视频 | 国产真人无遮挡作爱免费视频 | 成年美女黄网站色大免费全看 | 午夜肉伦伦影院 | 久久久精品国产sm最大网站 | 精品无码一区二区三区爱欲 | 国产超碰人人爽人人做人人添 | 亚洲小说春色综合另类 | 亚洲自偷自拍另类第1页 | 亚洲最大成人网站 | 欧美一区二区三区 | 中文字幕日韩精品一区二区三区 | 少妇性l交大片欧洲热妇乱xxx | 在线亚洲高清揄拍自拍一品区 | 中文字幕乱妇无码av在线 | 水蜜桃色314在线观看 | 欧洲vodafone精品性 | 久久精品国产一区二区三区 | 极品嫩模高潮叫床 | 亚洲欧美精品aaaaaa片 | 精品偷自拍另类在线观看 | 99视频精品全部免费免费观看 | 动漫av一区二区在线观看 | 2020久久超碰国产精品最新 | 国产真实乱对白精彩久久 | 欧美激情一区二区三区成人 | 2020久久超碰国产精品最新 | 女人高潮内射99精品 | 久久精品人人做人人综合试看 | 日本大香伊一区二区三区 | 精品夜夜澡人妻无码av蜜桃 | 午夜精品一区二区三区的区别 | 国产国产精品人在线视 | 中文字幕 人妻熟女 | 男人和女人高潮免费网站 | 久久熟妇人妻午夜寂寞影院 | 3d动漫精品啪啪一区二区中 | 免费国产黄网站在线观看 | 国产又粗又硬又大爽黄老大爷视 | 婷婷丁香六月激情综合啪 | 久久人妻内射无码一区三区 | 青草青草久热国产精品 | 成人片黄网站色大片免费观看 | 青青久在线视频免费观看 | 色婷婷av一区二区三区之红樱桃 | 亚洲成熟女人毛毛耸耸多 | 国语自产偷拍精品视频偷 | 无码国内精品人妻少妇 | 俺去俺来也在线www色官网 | 人人澡人人妻人人爽人人蜜桃 | 国产成人精品视频ⅴa片软件竹菊 | 国产sm调教视频在线观看 | 久久精品国产一区二区三区 | 午夜福利电影 | 久久久国产一区二区三区 | aⅴ亚洲 日韩 色 图网站 播放 | 国产色xx群视频射精 | 国产精品久久久午夜夜伦鲁鲁 | 国产精品亚洲一区二区三区喷水 | 1000部夫妻午夜免费 | 亲嘴扒胸摸屁股激烈网站 | 蜜臀av在线播放 久久综合激激的五月天 | 高清国产亚洲精品自在久久 | 久久久久亚洲精品男人的天堂 | 又大又硬又黄的免费视频 | 日产国产精品亚洲系列 | 成人aaa片一区国产精品 | 夜精品a片一区二区三区无码白浆 | 少妇无套内谢久久久久 | 中文精品久久久久人妻不卡 | 丰满人妻一区二区三区免费视频 | 爱做久久久久久 | 四虎4hu永久免费 | 久久人妻内射无码一区三区 | v一区无码内射国产 | 亚洲 激情 小说 另类 欧美 | 少妇一晚三次一区二区三区 | 国产精品亚洲一区二区三区喷水 | 久久久国产一区二区三区 | 久久精品无码一区二区三区 | 国产成人无码一二三区视频 | 精品国产一区二区三区av 性色 | 曰韩少妇内射免费播放 | 精品熟女少妇av免费观看 | 国产高清av在线播放 | 色婷婷综合中文久久一本 | 色爱情人网站 | 国色天香社区在线视频 | 特黄特色大片免费播放器图片 | 亚洲欧美日韩国产精品一区二区 | 蜜桃视频插满18在线观看 | 极品嫩模高潮叫床 | 亚洲爆乳无码专区 | 国产成人综合美国十次 | 亚洲 a v无 码免 费 成 人 a v | 中文字幕无码av波多野吉衣 | 精品成人av一区二区三区 | 强开小婷嫩苞又嫩又紧视频 | 国产人妻精品一区二区三区 | 久久精品99久久香蕉国产色戒 | 国产人妻精品午夜福利免费 | 国内精品九九久久久精品 | 国产免费观看黄av片 | 日韩精品一区二区av在线 | 青青青爽视频在线观看 | 亚洲日韩一区二区 | 国产农村乱对白刺激视频 | 欧美丰满老熟妇xxxxx性 | av无码不卡在线观看免费 | 中文字幕亚洲情99在线 | 88国产精品欧美一区二区三区 | 无码国产色欲xxxxx视频 | 欧美野外疯狂做受xxxx高潮 | 国产成人亚洲综合无码 | 999久久久国产精品消防器材 | 中文字幕无码av波多野吉衣 | 亚洲一区二区三区四区 | 亚洲一区av无码专区在线观看 | 又大又紧又粉嫩18p少妇 | 国内少妇偷人精品视频 | 亚洲精品久久久久avwww潮水 | 国产精品va在线观看无码 | 亚洲综合无码久久精品综合 | 狠狠色噜噜狠狠狠狠7777米奇 | 人人妻人人澡人人爽欧美一区九九 | 亚洲精品一区国产 | 少妇高潮喷潮久久久影院 | 国产精品无套呻吟在线 | 国产特级毛片aaaaaaa高清 | 久久99精品久久久久久动态图 | 九九在线中文字幕无码 | 久久久久久亚洲精品a片成人 | 正在播放老肥熟妇露脸 | 人妻天天爽夜夜爽一区二区 | 免费看男女做好爽好硬视频 | 久久国产精品偷任你爽任你 | 国产国语老龄妇女a片 | 熟妇人妻中文av无码 | 久久久精品456亚洲影院 | 欧美丰满老熟妇xxxxx性 | 国产97人人超碰caoprom | 国产av人人夜夜澡人人爽麻豆 | 亚洲日本va午夜在线电影 | 人人妻人人澡人人爽欧美一区九九 | 野外少妇愉情中文字幕 | 日本精品人妻无码77777 天堂一区人妻无码 | 国产乱人伦偷精品视频 | 亚洲日韩乱码中文无码蜜桃臀网站 | 妺妺窝人体色www在线小说 | 强奷人妻日本中文字幕 | 久久久久久av无码免费看大片 | 日韩精品无码免费一区二区三区 | 国产猛烈高潮尖叫视频免费 | 精品国偷自产在线视频 | 亚洲日本在线电影 | 九月婷婷人人澡人人添人人爽 | 人妻无码αv中文字幕久久琪琪布 | 国产精品亚洲综合色区韩国 | 精品日本一区二区三区在线观看 | 水蜜桃av无码 | √8天堂资源地址中文在线 | 国内精品九九久久久精品 | 色欲久久久天天天综合网精品 | 久久精品国产99精品亚洲 | 在线天堂新版最新版在线8 | 国产精品亚洲五月天高清 | 中文精品久久久久人妻不卡 | 亚洲国产午夜精品理论片 | 装睡被陌生人摸出水好爽 | 无码av免费一区二区三区试看 | 女人被男人爽到呻吟的视频 | 久久国产精品_国产精品 | 国产黄在线观看免费观看不卡 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 国产亚洲精品久久久久久久久动漫 | 国产成人精品久久亚洲高清不卡 | 国产特级毛片aaaaaaa高清 | 国产成人无码区免费内射一片色欲 | 人妻熟女一区 | 狂野欧美性猛xxxx乱大交 | 久久国语露脸国产精品电影 | 人人妻人人澡人人爽精品欧美 | 国产美女精品一区二区三区 | 国产成人无码区免费内射一片色欲 | 欧美高清在线精品一区 | 精品少妇爆乳无码av无码专区 | 国产精品久久久av久久久 | 精品久久综合1区2区3区激情 | 欧美人与牲动交xxxx | 成年女人永久免费看片 | 丰腴饱满的极品熟妇 | 亚洲无人区一区二区三区 | 日本乱人伦片中文三区 | 亚洲欧美精品aaaaaa片 | 99久久精品国产一区二区蜜芽 | 国产精品无码一区二区三区不卡 | 久久精品国产大片免费观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 精品国产一区二区三区四区 | 中文毛片无遮挡高清免费 | 亚洲 a v无 码免 费 成 人 a v | 丰满少妇弄高潮了www | 中文字幕 亚洲精品 第1页 | 国产xxx69麻豆国语对白 | 波多野结衣 黑人 | 亚洲一区二区三区偷拍女厕 | 人妻有码中文字幕在线 | 在线 国产 欧美 亚洲 天堂 | 乌克兰少妇xxxx做受 | 亚洲成av人影院在线观看 | 国产熟女一区二区三区四区五区 | 欧美 丝袜 自拍 制服 另类 | 性色欲网站人妻丰满中文久久不卡 | av香港经典三级级 在线 | 欧美阿v高清资源不卡在线播放 | 77777熟女视频在线观看 а天堂中文在线官网 | 香蕉久久久久久av成人 | 国产亚洲精品久久久久久久久动漫 | 午夜精品久久久内射近拍高清 | 在线亚洲高清揄拍自拍一品区 | 人妻夜夜爽天天爽三区 | 强开小婷嫩苞又嫩又紧视频 | 日本爽爽爽爽爽爽在线观看免 | 九九热爱视频精品 | 国产精品无码一区二区三区不卡 | 人妻互换免费中文字幕 | 国产午夜亚洲精品不卡下载 | 日本在线高清不卡免费播放 | 一二三四在线观看免费视频 | 一区二区传媒有限公司 | 沈阳熟女露脸对白视频 | 四十如虎的丰满熟妇啪啪 | 乌克兰少妇性做爰 | 欧美三级a做爰在线观看 | 激情综合激情五月俺也去 | 亚洲自偷自拍另类第1页 | 久精品国产欧美亚洲色aⅴ大片 | 精品一区二区不卡无码av | 国产色xx群视频射精 | 日本精品人妻无码77777 天堂一区人妻无码 | 亚洲gv猛男gv无码男同 | 亚洲国产成人a精品不卡在线 | 樱花草在线社区www | 性欧美疯狂xxxxbbbb | 蜜桃无码一区二区三区 | 亚洲欧美日韩综合久久久 | 国产成人无码av一区二区 | 在线亚洲高清揄拍自拍一品区 | 国产精品成人av在线观看 | 色综合久久久无码中文字幕 | 亚洲欧美色中文字幕在线 | 无套内谢的新婚少妇国语播放 | 熟妇人妻无码xxx视频 | 一本久道久久综合狠狠爱 | 中文字幕av日韩精品一区二区 | 人妻中文无码久热丝袜 | 色一情一乱一伦一视频免费看 | 无人区乱码一区二区三区 | 婷婷丁香五月天综合东京热 | 欧美兽交xxxx×视频 | 美女黄网站人色视频免费国产 | 性欧美大战久久久久久久 | 中文字幕av伊人av无码av | 熟女少妇在线视频播放 | 久久久久久国产精品无码下载 | 一本久道久久综合狠狠爱 | 性欧美熟妇videofreesex | 西西人体www44rt大胆高清 | 色婷婷欧美在线播放内射 | 亚洲成熟女人毛毛耸耸多 | 欧美性色19p | aⅴ亚洲 日韩 色 图网站 播放 | 永久免费精品精品永久-夜色 | 丝袜 中出 制服 人妻 美腿 | av香港经典三级级 在线 | 无码中文字幕色专区 | 亚洲精品国偷拍自产在线麻豆 | 一区二区三区乱码在线 | 欧洲 | 夜夜影院未满十八勿进 | 2019午夜福利不卡片在线 | 九月婷婷人人澡人人添人人爽 | 日本大香伊一区二区三区 | 少妇人妻偷人精品无码视频 | 又大又黄又粗又爽的免费视频 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 中文字幕无线码 | 色欲综合久久中文字幕网 | 欧美喷潮久久久xxxxx | 中文字幕无码av激情不卡 | 人妻人人添人妻人人爱 | 国产精品毛片一区二区 | 鲁鲁鲁爽爽爽在线视频观看 | 中文字幕无码免费久久9一区9 | 黑人玩弄人妻中文在线 | 欧美人与禽猛交狂配 | 激情内射日本一区二区三区 | 中文字幕无码热在线视频 | 国产精品爱久久久久久久 | 极品嫩模高潮叫床 | 国产极品美女高潮无套在线观看 | 巨爆乳无码视频在线观看 | 乱码午夜-极国产极内射 | 国产亚洲欧美日韩亚洲中文色 | 成 人 网 站国产免费观看 | 国产成人综合美国十次 | 99久久久无码国产精品免费 | 久久久久亚洲精品男人的天堂 | 动漫av一区二区在线观看 | 51国偷自产一区二区三区 | 国产精品高潮呻吟av久久 | 国产亚洲精品久久久久久国模美 | 97久久精品无码一区二区 | 国产精品美女久久久网av | 无码人妻丰满熟妇区五十路百度 | 欧美日韩一区二区综合 | 一个人看的视频www在线 | 免费观看激色视频网站 | 久久久亚洲欧洲日产国码αv | 一二三四社区在线中文视频 | 亚洲日本va中文字幕 | 亚洲色成人中文字幕网站 | 人妻少妇精品久久 | 成人一在线视频日韩国产 | 亚洲a无码综合a国产av中文 | 中文字幕av伊人av无码av | 国产午夜福利100集发布 | √天堂中文官网8在线 | 色一情一乱一伦 | 18禁止看的免费污网站 | 亚洲自偷自拍另类第1页 | 色老头在线一区二区三区 | 天天摸天天碰天天添 | 国产人妻大战黑人第1集 | 在线a亚洲视频播放在线观看 | 无码福利日韩神码福利片 | 国产无套内射久久久国产 | 国产精品福利视频导航 | 亚洲人成无码网www | 久久久久久亚洲精品a片成人 | 国产香蕉97碰碰久久人人 | 麻豆精品国产精华精华液好用吗 | 极品尤物被啪到呻吟喷水 | 鲁鲁鲁爽爽爽在线视频观看 | 日韩精品无码免费一区二区三区 | 亚洲一区av无码专区在线观看 | 欧美 丝袜 自拍 制服 另类 | 久久国产精品萌白酱免费 | 成人无码精品一区二区三区 | 自拍偷自拍亚洲精品被多人伦好爽 | 中文精品久久久久人妻不卡 | 亚洲午夜久久久影院 | 蜜桃视频插满18在线观看 | 成人精品视频一区二区 | 澳门永久av免费网站 | 动漫av网站免费观看 |