1251877Speter/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2251877Speter * 3251877Speter * Licensed under the Apache License, Version 2.0 (the "License"); 4251877Speter * you may not use this file except in compliance with the License. 5251877Speter * You may obtain a copy of the License at 6251877Speter * 7251877Speter * http://www.apache.org/licenses/LICENSE-2.0 8251877Speter * 9251877Speter * Unless required by applicable law or agreed to in writing, software 10251877Speter * distributed under the License is distributed on an "AS IS" BASIS, 11251877Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12251877Speter * See the License for the specific language governing permissions and 13251877Speter * limitations under the License. 14251877Speter */ 15251877Speter 16251877Speter#include <apr_pools.h> 17251877Speter 18251877Speter#include "serf.h" 19251877Speter#include "serf_bucket_util.h" 20251877Speter 21251877Speter 22251877Spetertypedef struct { 23251877Speter serf_bucket_t *stream; 24251877Speter} barrier_context_t; 25251877Speter 26251877Speter 27251877Speterserf_bucket_t *serf_bucket_barrier_create( 28251877Speter serf_bucket_t *stream, 29251877Speter serf_bucket_alloc_t *allocator) 30251877Speter{ 31251877Speter barrier_context_t *ctx; 32251877Speter 33251877Speter ctx = serf_bucket_mem_alloc(allocator, sizeof(*ctx)); 34251877Speter ctx->stream = stream; 35251877Speter 36251877Speter return serf_bucket_create(&serf_bucket_type_barrier, allocator, ctx); 37251877Speter} 38251877Speter 39251877Speterstatic apr_status_t serf_barrier_read(serf_bucket_t *bucket, 40251877Speter apr_size_t requested, 41251877Speter const char **data, apr_size_t *len) 42251877Speter{ 43251877Speter barrier_context_t *ctx = bucket->data; 44251877Speter 45251877Speter return serf_bucket_read(ctx->stream, requested, data, len); 46251877Speter} 47251877Speter 48251877Speterstatic apr_status_t serf_barrier_read_iovec(serf_bucket_t *bucket, 49251877Speter apr_size_t requested, 50251877Speter int vecs_size, struct iovec *vecs, 51251877Speter int *vecs_used) 52251877Speter{ 53251877Speter barrier_context_t *ctx = bucket->data; 54251877Speter 55251877Speter return serf_bucket_read_iovec(ctx->stream, requested, vecs_size, vecs, 56251877Speter vecs_used); 57251877Speter} 58251877Speter 59251877Speterstatic apr_status_t serf_barrier_readline(serf_bucket_t *bucket, 60251877Speter int acceptable, int *found, 61251877Speter const char **data, apr_size_t *len) 62251877Speter{ 63251877Speter barrier_context_t *ctx = bucket->data; 64251877Speter 65251877Speter return serf_bucket_readline(ctx->stream, acceptable, found, data, len); 66251877Speter} 67251877Speter 68251877Speterstatic apr_status_t serf_barrier_peek(serf_bucket_t *bucket, 69251877Speter const char **data, 70251877Speter apr_size_t *len) 71251877Speter{ 72251877Speter barrier_context_t *ctx = bucket->data; 73251877Speter 74251877Speter return serf_bucket_peek(ctx->stream, data, len); 75251877Speter} 76251877Speter 77251877Speterstatic void serf_barrier_destroy(serf_bucket_t *bucket) 78251877Speter{ 79251877Speter /* The intent of this bucket is not to let our wrapped buckets be 80251877Speter * destroyed. */ 81251877Speter 82251877Speter /* The option is for us to go ahead and 'eat' this bucket now, 83251877Speter * or just ignore the deletion entirely. 84251877Speter */ 85251877Speter serf_default_destroy_and_data(bucket); 86251877Speter} 87251877Speter 88251877Speterconst serf_bucket_type_t serf_bucket_type_barrier = { 89251877Speter "BARRIER", 90251877Speter serf_barrier_read, 91251877Speter serf_barrier_readline, 92251877Speter serf_barrier_read_iovec, 93251877Speter serf_default_read_for_sendfile, 94251877Speter serf_default_read_bucket, 95251877Speter serf_barrier_peek, 96251877Speter serf_barrier_destroy, 97251877Speter}; 98