⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apr_buckets.h

📁 一套很值得分析的短信SMS开发源代码。是我今年早些时候从taobao上买来的。但我现在也没看完(先说清楚
💻 H
📖 第 1 页 / 共 4 页
字号:
 * destroy the bucket it points to, then APR_BRIGADE_FOREACH
 * will have no way to find out what bucket to use for its next
 * iteration.  The reason for this can be seen by looking closely
 * at the equivalent loops given in the tip above.  So, for example,
 * if you are writing a loop that empties out a brigade one bucket
 * at a time, APR_BRIGADE_FOREACH just won't work for you.  Do it
 * by hand, like so:
 * <pre>
 *      while (!APR_BRIGADE_EMPTY(b)) {
 *          e = APR_BRIGADE_FIRST(b);
 *          ...
 *          apr_bucket_delete(e);
 *      }
 * </pre>
 * @deprecated This macro causes more headaches than it's worth.  Use
 * one of the alternatives documented here instead; the clarity gained
 * in what's really going on is well worth the extra line or two of code.
 * This macro will be removed at some point in the future.
 */
#define APR_BRIGADE_FOREACH(e, b)					\
	APR_RING_FOREACH((e), &(b)->list, apr_bucket, link)

/**
 * Insert a list of buckets at the front of a brigade
 * @param b The brigade to add to
 * @param e The first bucket in a list of buckets to insert
 */
#define APR_BRIGADE_INSERT_HEAD(b, e) do {				\
	apr_bucket *ap__b = (e);                                        \
	APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((b));				\
    } while (0)

/**
 * Insert a list of buckets at the end of a brigade
 * @param b The brigade to add to
 * @param e The first bucket in a list of buckets to insert
 */
#define APR_BRIGADE_INSERT_TAIL(b, e) do {				\
	apr_bucket *ap__b = (e);					\
	APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((b));				\
    } while (0)

/**
 * Concatenate brigade b onto the end of brigade a, leaving brigade b empty
 * @param a The first brigade
 * @param b The second brigade
 */
#define APR_BRIGADE_CONCAT(a, b) do {					\
        APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((a));				\
    } while (0)

/**
 * Prepend brigade b onto the beginning of brigade a, leaving brigade b empty
 * @param a The first brigade
 * @param b The second brigade
 */
#define APR_BRIGADE_PREPEND(a, b) do {					\
        APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link);	\
        APR_BRIGADE_CHECK_CONSISTENCY((a));				\
    } while (0)

/**
 * Insert a list of buckets before a specified bucket
 * @param a The bucket to insert before
 * @param b The buckets to insert
 */
#define APR_BUCKET_INSERT_BEFORE(a, b) do {				\
	apr_bucket *ap__a = (a), *ap__b = (b);				\
	APR_RING_INSERT_BEFORE(ap__a, ap__b, link);			\
        APR_BUCKET_CHECK_CONSISTENCY(ap__a);				\
    } while (0)

/**
 * Insert a list of buckets after a specified bucket
 * @param a The bucket to insert after
 * @param b The buckets to insert
 */
#define APR_BUCKET_INSERT_AFTER(a, b) do {				\
	apr_bucket *ap__a = (a), *ap__b = (b);				\
	APR_RING_INSERT_AFTER(ap__a, ap__b, link);			\
        APR_BUCKET_CHECK_CONSISTENCY(ap__a);				\
    } while (0)

/**
 * Get the next bucket in the list
 * @param e The current bucket
 * @return The next bucket
 */
#define APR_BUCKET_NEXT(e)	APR_RING_NEXT((e), link)
/**
 * Get the previous bucket in the list
 * @param e The current bucket
 * @return The previous bucket
 */
#define APR_BUCKET_PREV(e)	APR_RING_PREV((e), link)

/**
 * Remove a bucket from its bucket brigade
 * @param e The bucket to remove
 */
#define APR_BUCKET_REMOVE(e)	APR_RING_REMOVE((e), link)

/**
 * Initialize a new bucket's prev/next pointers
 * @param e The bucket to initialize
 */
#define APR_BUCKET_INIT(e)	APR_RING_ELEM_INIT((e), link)

/**
 * Determine if a bucket contains metadata.  An empty bucket is
 * safe to arbitrarily remove if and only if this is false.
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_METADATA(e)    ((e)->type->is_metadata)

/**
 * Determine if a bucket is a FLUSH bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_FLUSH(e)       ((e)->type == &apr_bucket_type_flush)
/**
 * Determine if a bucket is an EOS bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_EOS(e)         ((e)->type == &apr_bucket_type_eos)
/**
 * Determine if a bucket is a FILE bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_FILE(e)        ((e)->type == &apr_bucket_type_file)
/**
 * Determine if a bucket is a PIPE bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_PIPE(e)        ((e)->type == &apr_bucket_type_pipe)
/**
 * Determine if a bucket is a SOCKET bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_SOCKET(e)      ((e)->type == &apr_bucket_type_socket)
/**
 * Determine if a bucket is a HEAP bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_HEAP(e)        ((e)->type == &apr_bucket_type_heap)
/**
 * Determine if a bucket is a TRANSIENT bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_TRANSIENT(e)   ((e)->type == &apr_bucket_type_transient)
/**
 * Determine if a bucket is a IMMORTAL bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_IMMORTAL(e)    ((e)->type == &apr_bucket_type_immortal)
#if APR_HAS_MMAP
/**
 * Determine if a bucket is a MMAP bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_MMAP(e)        ((e)->type == &apr_bucket_type_mmap)
#endif
/**
 * Determine if a bucket is a POOL bucket
 * @param e The bucket to inspect
 * @return true or false
 */
#define APR_BUCKET_IS_POOL(e)        ((e)->type == &apr_bucket_type_pool)

/*
 * General-purpose reference counting for the various bucket types.
 *
 * Any bucket type that keeps track of the resources it uses (i.e.
 * most of them except for IMMORTAL, TRANSIENT, and EOS) needs to
 * attach a reference count to the resource so that it can be freed
 * when the last bucket that uses it goes away. Resource-sharing may
 * occur because of bucket splits or buckets that refer to globally
 * cached data. */

/** @see apr_bucket_refcount */
typedef struct apr_bucket_refcount apr_bucket_refcount;
/**
 * The structure used to manage the shared resource must start with an
 * apr_bucket_refcount which is updated by the general-purpose refcount
 * code. A pointer to the bucket-type-dependent private data structure
 * can be cast to a pointer to an apr_bucket_refcount and vice versa.
 */
struct apr_bucket_refcount {
    /** The number of references to this bucket */
    int          refcount;
};

/*  *****  Reference-counted bucket types  *****  */

/** @see apr_bucket_heap */
typedef struct apr_bucket_heap apr_bucket_heap;
/**
 * A bucket referring to data allocated off the heap.
 */
struct apr_bucket_heap {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The start of the data actually allocated.  This should never be
     * modified, it is only used to free the bucket.
     */
    char    *base;
    /** how much memory was allocated */
    apr_size_t  alloc_len;
    /** function to use to delete the data */
    void (*free_func)(void *data);
};

/** @see apr_bucket_pool */
typedef struct apr_bucket_pool apr_bucket_pool;
/**
 * A bucket referring to data allocated from a pool
 */
struct apr_bucket_pool {
    /** The pool bucket must be able to be easily morphed to a heap
     * bucket if the pool gets cleaned up before all references are
     * destroyed.  This apr_bucket_heap structure is populated automatically
     * when the pool gets cleaned up, and subsequent calls to pool_read()
     * will result in the apr_bucket in question being morphed into a
     * regular heap bucket.  (To avoid having to do many extra refcount
     * manipulations and b->data manipulations, the apr_bucket_pool
     * struct actually *contains* the apr_bucket_heap struct that it
     * will become as its first element; the two share their
     * apr_bucket_refcount members.)
     */
    apr_bucket_heap  heap;
    /** The block of data actually allocated from the pool.
     * Segments of this block are referenced by adjusting
     * the start and length of the apr_bucket accordingly.
     * This will be NULL after the pool gets cleaned up.
     */
    const char *base;
    /** The pool the data was allocated from.  When the pool
     * is cleaned up, this gets set to NULL as an indicator
     * to pool_read() that the data is now on the heap and
     * so it should morph the bucket into a regular heap
     * bucket before continuing.
     */
    apr_pool_t *pool;
    /** The freelist this structure was allocated from, which is
     * needed in the cleanup phase in order to allocate space on the heap
     */
    apr_bucket_alloc_t *list;
};

#if APR_HAS_MMAP
/** @see apr_bucket_mmap */
typedef struct apr_bucket_mmap apr_bucket_mmap;
/**
 * A bucket referring to an mmap()ed file
 */
struct apr_bucket_mmap {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The mmap this sub_bucket refers to */
    apr_mmap_t *mmap;
};
#endif

/** @see apr_bucket_file */
typedef struct apr_bucket_file apr_bucket_file;
/**
 * A bucket referring to an file
 */
struct apr_bucket_file {
    /** Number of buckets using this memory */
    apr_bucket_refcount  refcount;
    /** The file this bucket refers to */
    apr_file_t *fd;
    /** The pool into which any needed structures should
     *  be created while reading from this file bucket */
    apr_pool_t *readpool;
#if APR_HAS_MMAP
    /** Whether this bucket should be memory-mapped if
     *  a caller tries to read from it */
    int can_mmap;
#endif /* APR_HAS_MMAP */
};

/** @see apr_bucket_structs */
typedef union apr_bucket_structs apr_bucket_structs;
/**
 * A union of all bucket structures so we know what
 * the max size is.
 */
union apr_bucket_structs {
    apr_bucket      b;      /**< Bucket */
    apr_bucket_heap heap;   /**< Heap */
    apr_bucket_pool pool;   /**< Pool */
#if APR_HAS_MMAP
    apr_bucket_mmap mmap;   /**< MMap */
#endif
    apr_bucket_file file;   /**< File */
};

/**
 * The amount that apr_bucket_alloc() should allocate in the common case.
 * Note: this is twice as big as apr_bucket_structs to allow breathing
 * room for third-party bucket types.
 */
#define APR_BUCKET_ALLOC_SIZE  APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs))

/*  *****  Bucket Brigade Functions  *****  */
/**
 * Create a new bucket brigade.  The bucket brigade is originally empty.
 * @param p The pool to associate with the brigade.  Data is not allocated out
 *          of the pool, but a cleanup is registered.
 * @param list The bucket allocator to use
 * @return The empty bucket brigade
 */
APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
                                                     apr_bucket_alloc_t *list);

/**
 * destroy an entire bucket brigade.  This includes destroying all of the
 * buckets within the bucket brigade's bucket list. 
 * @param b The bucket brigade to destroy
 */
APU_DECLARE(apr_status_t) apr_brigade_destroy(apr_bucket_brigade *b);

/**
 * empty out an entire bucket brigade.  This includes destroying all of the
 * buckets within the bucket brigade's bucket list.  This is similar to
 * apr_brigade_destroy(), except that it does not deregister the brigade's
 * pool cleanup function.
 * @param data The bucket brigade to clean up
 * @remark Generally, you should use apr_brigade_destroy().  This function
 *         can be useful in situations where you have a single brigade that
 *         you wish to reuse many times by destroying all of the buckets in
 *         the brigade and putting new buckets into it later.
 */
APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data);

/**
 * Split a bucket brigade into two, such that the given bucket is the
 * first in the new bucket brigade. This function is useful when a
 * filter wants to pass only the initial part of a brigade to the next
 * filter.
 * @param b The brigade to split
 * @param e The first element of the new brigade
 * @return The new brigade
 */
APU_DECLARE(apr_bucket_brigade *) apr_brigade_split(apr_bucket_brigade *b,
                                                    apr_bucket *e);

/**
 * Partition a bucket brigade at a given offset (in bytes from the start of
 * the brigade).  This is useful whenever a filter wants to use known ranges
 * of bytes from the brigade; the ranges can even overlap.
 * @param b The brigade to partition
 * @param point The offset at which to partition the brigade
 * @param after_point Returns a pointer to the first bucket after the partition
 */
APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
                                                apr_off_t point,
                                                apr_bucket **after_point);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -