| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 | |
| 6 #ifndef PPAPI_MAIN_PPAPI_QUEUE_H | |
| 7 #define PPAPI_MAIN_PPAPI_QUEUE_H | |
| 8 | |
| 9 #include <stdint.h> | |
| 10 | |
| 11 // | |
| 12 // PPAPIQueue | |
| 13 // | |
| 14 // PPAPIQueue is a single producer/single consumer lockless queue. This | |
| 15 // implementation is PPAPI friendly because it prevents the main thread from | |
| 16 // ever needing to lock. In addition, allocation and destruction of messages | |
| 17 // happens on the same thread, allowing for lockless message allocation as well. | |
| 18 // | |
| 19 // Messages pass through four states in order: | |
| 20 // AddNewMessage - The message is added to the queue by the producer | |
| 21 // and the memory is fenced to ensure it is visible. Once the fence | |
| 22 // returns, the write pointer is incremented to signal it's available to | |
| 23 // the consumer. NOTE: NULL messages are illegal. | |
| 24 // | |
| 25 // AcquireTopMessage - Next the message is acquired by the consumer thread. | |
| 26 // At this point, the consumer is considered to be examining the payload so | |
| 27 // we do not increment the read pointer yet to prevent deletion. NOTE: it | |
| 28 // is illegal to acquire the next message until the previous one is released. | |
| 29 // | |
| 30 // ReleaseTopMessage - Now the consumer signals that it is no longer looking | |
| 31 // at the message by incremented the read pointer. The producer is free to | |
| 32 // release or reuse the payload. | |
| 33 // | |
| 34 // RemoveStaleMessage - The message is no longer visible to the consumer, so | |
| 35 // it is returned to the producer to be reused or destroyed. It's location | |
| 36 // in the queue is set to NULL to signal that a new message may be added in | |
| 37 // that slot. | |
| 38 // | |
| 39 class PPAPIQueue { | |
| 40 public: | |
| 41 PPAPIQueue(); | |
| 42 ~PPAPIQueue(); | |
| 43 | |
| 44 // | |
| 45 // Producer API | |
| 46 // | |
| 47 // First, the producer must set the queue size before any operation can | |
| 48 // take place. Next, before adding a message, clear space in the queue, | |
| 49 // by removing stale messages. Adding a new message will return TRUE if | |
| 50 // space is available, otherwise FALSE is returned and it's up to the | |
| 51 // application developer to decide what to do. | |
| 52 // | |
| 53 bool SetSize(uint32_t queue_size); | |
| 54 bool AddNewMessage(void* msg); | |
| 55 void* RemoveStaleMessage(); | |
| 56 | |
| 57 // | |
| 58 // Consumer API | |
| 59 // | |
| 60 // The reader will attempt to Acquire the top message, if one is not | |
| 61 // available NULL will be returned. Once the consumer is done with the | |
| 62 // message, ReleaseTopMessage is called to signal that the payload is no | |
| 63 // longer visible to the consumer and can be recycled or destroyed. | |
| 64 // Since messages are freed in order, it is required that messages are | |
| 65 // consumed in order. For this reason, it is illegal to call Acquire again | |
| 66 // after a non-NULL message pointer is returned, until Release is called on | |
| 67 // the old message. This means the consumer can only look at one message | |
| 68 // at a time. To look at multiple messages at once, the consumer would | |
| 69 // need to make a copy and release the top message. | |
| 70 // | |
| 71 void* AcquireTopMessage(); | |
| 72 void ReleaseTopMessage(void* msg); | |
| 73 | |
| 74 private: | |
| 75 uint32_t read_; | |
| 76 uint32_t write_; | |
| 77 uint32_t freed_; | |
| 78 uint32_t size_; | |
| 79 void* last_msg_; | |
| 80 void** array_; | |
| 81 }; | |
| 82 | |
| 83 | |
| 84 #endif // PPAPI_MAIN_PPAPI_QUEUE_H | |
| OLD | NEW |