1APACHE COMMONS: serf -*-indented-text-*- 2 3 4TOPICS 5 6 1. Introduction 7 2. Thread Safety 8 3. Pool Usage 9 4. Bucket Read Functions 10 5. Versioning 11 6. Bucket lifetimes 12 13 14----------------------------------------------------------------------------- 15 161. INTRODUCTION 17 18This document details various design choices for the serf library. It 19is intended to be a guide for serf developers. Of course, these design 20principles, choices made, etc are a good source of information for 21users of the serf library, too. 22 23 24----------------------------------------------------------------------------- 25 262. THREAD SAFETY 27 28The serf library should contain no mutable globals, making it is safe 29to use in a multi-threaded environment. 30 31Each "object" within the system does not need to be used from multiple 32threads at a time. Thus, they require no internal mutexes, and can 33disable mutexes within APR objects where applicable (e.g. pools that 34are created). 35 36The objects should not have any thread affinity (i.e. don't use 37thread-local storage). This enables an application to use external 38mutexes to guard entry to the serf objects, which then allows the 39objects to be used from multiple threads. 40 41 42----------------------------------------------------------------------------- 43 443. POOL USAGE 45 46For general information on the proper use of pools, please see: 47 48 http://cvs.apache.org/viewcvs/*checkout*/apr/docs/pool-design.html 49 50Within serf itself, the buckets introduce a significant issue related 51to pools. Since it is very possible to end up creating *many* buckets 52within a transaction, and that creation could be proportional to an 53incoming or outgoing data stream, a lot of care must be take to avoid 54tying bucket allocations to pools. If a bucket allocated any internal 55memory against a pool, and if that bucket is created an unbounded 56number of times, then the pool memory could be exhausted. 57 58Thus, buckets are allocated using a custom allocator which allows the 59memory to be freed when that bucket is no longer needed. This 60contrasts with pools where the "free" operation occurs over a large 61set of objects, which is problematic if some are still in use. 62 63### need more explanation of strategy/solution ... 64 65 66----------------------------------------------------------------------------- 67 684. BUCKET READ FUNCTIONS 69 70The bucket reading and peek functions must not block. Each read 71function should return (up to) the specified amount of data. If 72SERF_READ_ALL_AVAIL is passed, then the function should provide 73whatever is immediately available, without blocking. 74 75The peek function does not take a requested length because it is 76non-destructive. It is not possible to "read past" any barrier with a 77peek function. Thus, peek should operate like SERF_READ_ALL_AVAIL. 78 79The return values from the read functions should follow this general 80pattern: 81 82 APR_SUCCESS Some data was returned, and the caller can 83 immediately call the read function again to read 84 more data. 85 86 NOTE: when bucket behavior tracking is enabled, 87 then you must read more data from this bucket 88 before returning to the serf context loop. If a 89 bucket is not completely drained first, then it is 90 possible to deadlock (the server might not read 91 anything until you read everything it has already 92 given to you). 93 94 APR_EAGAIN Some data was returned, but no more is available 95 for now. The caller must "wait for a bit" or wait 96 for some event before attempting to read again 97 (basically, this simply means re-run the serf 98 context loop). Though it shouldn't be done, reading 99 again will, in all likelihood, return zero length 100 data and APR_EAGAIN again. 101 102 NOTE: when bucket behavior tracking is enabled, 103 then it is illegal to immediately read a bucket 104 again after it has returned APR_EAGAIN. You must 105 run the serf context loop again to (potentially) 106 fetch more data for the bucket. 107 108 APR_EOF Some data was returned, and this bucket has no more 109 data available and should not be read again. If you 110 happen to read it again, then it will return zero 111 length data and APR_EOF. 112 113 NOTE: when bucket behavior tracking is enabled, 114 then it is illegal to read this bucket ever again. 115 116 other An error has occurred. No data was returned. The 117 returned length is undefined. 118 119In the above paragraphs, when it says "some data was returned", note 120that this could be data of length zero. 121 122If a length of zero is returned, then the caller should not attempt to 123dereference the data pointer. It may be invalid. Note that there is no 124reason to dereference that pointer, since it doesn't point to any 125valid data. 126 127Any data returned by the bucket should live as long as the bucket, or 128until the next read or peek occurs. 129 130The read_bucket function falls into a very different pattern. See its 131doc string for more information. 132 133 134----------------------------------------------------------------------------- 135 1365. VERSIONING 137 138The serf project uses the APR versioning guidelines described here: 139 140 http://apr.apache.org/versioning.html 141 142 143----------------------------------------------------------------------------- 144 1456. BUCKET LIFETIMES 146 147### flesh out. basically: if you hold a bucket pointer, then you own 148### it. passing a bucket into another transfers ownership. use barrier 149### buckets to limit destruction of a tree of buckets. 150 151 152----------------------------------------------------------------------------- 153