Chromium Code Reviews| Index: chromecast/media/cma/ipc/media_message_fifo.h |
| diff --git a/chromecast/media/cma/ipc/media_message_fifo.h b/chromecast/media/cma/ipc/media_message_fifo.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e1e2d56f82a2699adb6e7ac6d5b9589eea43dcf3 |
| --- /dev/null |
| +++ b/chromecast/media/cma/ipc/media_message_fifo.h |
| @@ -0,0 +1,147 @@ |
| +// Copyright 2014 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#ifndef CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_FIFO_H_ |
| +#define CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_FIFO_H_ |
| + |
| +#include <list> |
| + |
| +#include "base/atomicops.h" |
| +#include "base/basictypes.h" |
| +#include "base/callback.h" |
| +#include "base/logging.h" |
| +#include "base/macros.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "base/threading/thread_checker.h" |
| + |
| +namespace chromecast { |
| +namespace media { |
| +class MediaMemoryChunk; |
| +class MediaMessage; |
| +class MediaMessageFlag; |
| + |
| +class MediaMessageFifo { |
| + public: |
| + // Creates a media message fifo using |mem| as the underlying serialized |
| + // structure. |
| + // If |init| is true, the underlying fifo structure is initialized. |
| + MediaMessageFifo(scoped_ptr<MediaMemoryChunk> mem, bool init); |
| + ~MediaMessageFifo(); |
| + |
| + // When the consumer and the feeder are living in two different processes, |
| + // we might want to convey some messages between these two processes to notify |
| + // about some fifo activity. |
| + void ObserveReadActivity(const base::Closure& read_event_cb); |
| + void ObserveWriteActivity(const base::Closure& write_event_cb); |
| + |
| + // Reserves a writeable block of memory at the back of the fifo, |
| + // corresponding to the serialized structure of the message. |
| + scoped_ptr<MediaMemoryChunk> ReserveMemory(size_t size); |
|
xhwang
2014/09/03 17:40:33
What if the memory of |size| cannot be reserved? W
damienv1
2014/09/03 23:59:05
Done.
|
| + |
| + // Pop a message from the queue. |
| + // Returns a null pointer if there is no message left. |
| + scoped_ptr<MediaMessage> Pop(); |
| + |
| + // Flush the fifo. |
| + void Flush(); |
| + |
| + private: |
| + struct Descriptor { |
| + size_t size; |
| + size_t rd_offset; |
| + size_t wr_offset; |
| + |
| + // Ensure the first item has the same alignment as an int64. |
| + int64 first_item; |
| + }; |
| + |
| + // Add some accessors to ensure security on the browser process side. |
| + size_t current_rd_offset() const; |
| + size_t current_wr_offset() const; |
| + size_t internal_rd_offset() const { |
| + DCHECK_LT(internal_rd_offset_, size_); |
| + return internal_rd_offset_; |
| + } |
| + size_t internal_wr_offset() const { |
| + DCHECK_LT(internal_wr_offset_, size_); |
| + return internal_wr_offset_; |
| + } |
| + |
| + // Reserve a block of free memory without doing any check on the available |
| + // space. Invoke this function only when all the checks have been done. |
| + scoped_ptr<MediaMemoryChunk> ReserveMemoryNoCheck(size_t size); |
| + |
| + // Invoked each time there is a memory region in the free space of the fifo |
| + // that has possibly been written. |
| + void OnWrMemoryReleased(); |
| + |
| + // Invoked each time there is a memory region in the allocated space |
| + // of the fifo that has possibly been released. |
| + void OnRdMemoryReleased(); |
| + |
| + void CommitRead(size_t new_rd_offset); |
| + void CommitWrite(size_t new_wr_offset); |
| + void CommitInternalRead(size_t new_rd_offset); |
| + void CommitInternalWrite(size_t new_wr_offset); |
| + |
| + // Having a thread checker does not mean that the feeder and the consumer |
| + // cannot live on different threads. If the consumer and the feeder are |
| + // living on two different threads, then there should be one MediaMessageFifo |
| + // instance for the feeder side and another instance for the consumer side, |
| + // both pointing to the same fifo memory structure. |
| + base::ThreadChecker thread_checker_; |
|
xhwang
2014/09/03 17:40:33
Given the comments and w/o looking at the impl, I
damienv1
2014/09/03 23:59:06
I updated the comment. Hope it's less confusing.
|
| + |
| + // Callbacks invoked to notify either of some read or write activity on the |
| + // fifo. This is especially useful when the feeder and consumer are living in |
| + // two different processes. |
| + base::Closure read_event_cb_; |
| + base::Closure write_event_cb_; |
| + |
| + // The serialized structure of the fifo. |
| + scoped_ptr<MediaMemoryChunk> mem_; |
| + |
| + // The size in bytes of the fifo is cached locally for security purpose. |
| + // (the renderer process cannot modify the size and make the browser process |
| + // access out of range addresses). |
| + size_t size_; |
| + |
| + // TODO(damienv): This is a work-around since atomicops.h does not define |
| + // an atomic size_t type. |
| +#if SIZE_MAX == UINT32_MAX |
| + typedef base::subtle::Atomic32 AtomicSize; |
| +#elif SIZE_MAX == UINT64_MAX |
| + typedef base::subtle::Atomic64 AtomicSize; |
| +#elif |
| +#error "Unsupported size_t" |
| +#endif |
| + AtomicSize* rd_offset_; |
| + AtomicSize* wr_offset_; |
| + |
| + // Internal read offset: this is where data is actually read from. |
| + // The external offset |rd_offset_| is only used to protect data from being |
| + // overwritten by the feeder. |
| + // At any time, the internal read pointer must be between the external read |
| + // offset and the write offset (circular fifo definition of "between"). |
| + size_t internal_rd_offset_; |
| + size_t internal_wr_offset_; |
| + |
| + // Note: all the memory read/write are followed by a memory fence before |
| + // updating the rd/wr pointer. |
| + void* base_; |
| + |
| + std::list<scoped_refptr<MediaMessageFlag> > rd_flags_; |
| + std::list<scoped_refptr<MediaMessageFlag> > wr_flags_; |
| + |
| + base::WeakPtrFactory<MediaMessageFifo> weak_factory_; |
| + base::WeakPtr<MediaMessageFifo> weak_this_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(MediaMessageFifo); |
| +}; |
| + |
| +} // namespace media |
| +} // namespace chromecast |
| + |
| +#endif // CHROMECAST_MEDIA_CMA_IPC_MEDIA_MESSAGE_FIFO_H_ |