1251877SpeterAPACHE COMMONS: serf -*-indented-text-*- 2251877Speter 3251877Speter 4251877SpeterTOPICS 5251877Speter 6251877Speter 1. Introduction 7251877Speter 2. Thread Safety 8251877Speter 3. Pool Usage 9251877Speter 4. Bucket Read Functions 10251877Speter 5. Versioning 11251877Speter 6. Bucket lifetimes 12251877Speter 13251877Speter 14251877Speter----------------------------------------------------------------------------- 15251877Speter 16251877Speter1. INTRODUCTION 17251877Speter 18251877SpeterThis document details various design choices for the serf library. It 19251877Speteris intended to be a guide for serf developers. Of course, these design 20251877Speterprinciples, choices made, etc are a good source of information for 21251877Speterusers of the serf library, too. 22251877Speter 23251877Speter 24251877Speter----------------------------------------------------------------------------- 25251877Speter 26251877Speter2. THREAD SAFETY 27251877Speter 28251877SpeterThe serf library should contain no mutable globals, making it is safe 29251877Speterto use in a multi-threaded environment. 30251877Speter 31251877SpeterEach "object" within the system does not need to be used from multiple 32251877Speterthreads at a time. Thus, they require no internal mutexes, and can 33251877Speterdisable mutexes within APR objects where applicable (e.g. pools that 34251877Speterare created). 35251877Speter 36251877SpeterThe objects should not have any thread affinity (i.e. don't use 37251877Speterthread-local storage). This enables an application to use external 38251877Spetermutexes to guard entry to the serf objects, which then allows the 39251877Speterobjects to be used from multiple threads. 40251877Speter 41251877Speter 42251877Speter----------------------------------------------------------------------------- 43251877Speter 44251877Speter3. POOL USAGE 45251877Speter 46251877SpeterFor general information on the proper use of pools, please see: 47251877Speter 48251877Speter http://cvs.apache.org/viewcvs/*checkout*/apr/docs/pool-design.html 49251877Speter 50251877SpeterWithin serf itself, the buckets introduce a significant issue related 51251877Speterto pools. Since it is very possible to end up creating *many* buckets 52251877Speterwithin a transaction, and that creation could be proportional to an 53251877Speterincoming or outgoing data stream, a lot of care must be take to avoid 54251877Spetertying bucket allocations to pools. If a bucket allocated any internal 55251877Spetermemory against a pool, and if that bucket is created an unbounded 56251877Speternumber of times, then the pool memory could be exhausted. 57251877Speter 58251877SpeterThus, buckets are allocated using a custom allocator which allows the 59251877Spetermemory to be freed when that bucket is no longer needed. This 60251877Spetercontrasts with pools where the "free" operation occurs over a large 61251877Speterset of objects, which is problematic if some are still in use. 62251877Speter 63251877Speter### need more explanation of strategy/solution ... 64251877Speter 65251877Speter 66251877Speter----------------------------------------------------------------------------- 67251877Speter 68251877Speter4. BUCKET READ FUNCTIONS 69251877Speter 70251877SpeterThe bucket reading and peek functions must not block. Each read 71251877Speterfunction should return (up to) the specified amount of data. If 72251877SpeterSERF_READ_ALL_AVAIL is passed, then the function should provide 73251877Speterwhatever is immediately available, without blocking. 74251877Speter 75251877SpeterThe peek function does not take a requested length because it is 76251877Speternon-destructive. It is not possible to "read past" any barrier with a 77251877Speterpeek function. Thus, peek should operate like SERF_READ_ALL_AVAIL. 78251877Speter 79251877SpeterThe return values from the read functions should follow this general 80251877Speterpattern: 81251877Speter 82251877Speter APR_SUCCESS Some data was returned, and the caller can 83251877Speter immediately call the read function again to read 84251877Speter more data. 85251877Speter 86251877Speter NOTE: when bucket behavior tracking is enabled, 87251877Speter then you must read more data from this bucket 88251877Speter before returning to the serf context loop. If a 89251877Speter bucket is not completely drained first, then it is 90251877Speter possible to deadlock (the server might not read 91251877Speter anything until you read everything it has already 92251877Speter given to you). 93251877Speter 94251877Speter APR_EAGAIN Some data was returned, but no more is available 95251877Speter for now. The caller must "wait for a bit" or wait 96251877Speter for some event before attempting to read again 97251877Speter (basically, this simply means re-run the serf 98251877Speter context loop). Though it shouldn't be done, reading 99251877Speter again will, in all likelihood, return zero length 100251877Speter data and APR_EAGAIN again. 101251877Speter 102251877Speter NOTE: when bucket behavior tracking is enabled, 103251877Speter then it is illegal to immediately read a bucket 104251877Speter again after it has returned APR_EAGAIN. You must 105251877Speter run the serf context loop again to (potentially) 106251877Speter fetch more data for the bucket. 107251877Speter 108251877Speter APR_EOF Some data was returned, and this bucket has no more 109251877Speter data available and should not be read again. If you 110251877Speter happen to read it again, then it will return zero 111251877Speter length data and APR_EOF. 112251877Speter 113251877Speter NOTE: when bucket behavior tracking is enabled, 114251877Speter then it is illegal to read this bucket ever again. 115251877Speter 116251877Speter other An error has occurred. No data was returned. The 117251877Speter returned length is undefined. 118251877Speter 119251877SpeterIn the above paragraphs, when it says "some data was returned", note 120251877Speterthat this could be data of length zero. 121251877Speter 122251877SpeterIf a length of zero is returned, then the caller should not attempt to 123251877Speterdereference the data pointer. It may be invalid. Note that there is no 124251877Speterreason to dereference that pointer, since it doesn't point to any 125251877Spetervalid data. 126251877Speter 127251877SpeterAny data returned by the bucket should live as long as the bucket, or 128251877Speteruntil the next read or peek occurs. 129251877Speter 130251877SpeterThe read_bucket function falls into a very different pattern. See its 131251877Speterdoc string for more information. 132251877Speter 133251877Speter 134251877Speter----------------------------------------------------------------------------- 135251877Speter 136251877Speter5. VERSIONING 137251877Speter 138251877SpeterThe serf project uses the APR versioning guidelines described here: 139251877Speter 140251877Speter http://apr.apache.org/versioning.html 141251877Speter 142251877Speter 143251877Speter----------------------------------------------------------------------------- 144251877Speter 145251877Speter6. BUCKET LIFETIMES 146251877Speter 147251877Speter### flesh out. basically: if you hold a bucket pointer, then you own 148251877Speter### it. passing a bucket into another transfers ownership. use barrier 149251877Speter### buckets to limit destruction of a tree of buckets. 150251877Speter 151251877Speter 152251877Speter----------------------------------------------------------------------------- 153