OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium OS 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 #ifndef VOLUME_READER_JAVSCRIPT_STREAM_H_ | |
6 #define VOLUME_READER_JAVSCRIPT_STREAM_H_ | |
7 | |
8 #include <pthread.h> | |
9 | |
10 #include "archive.h" | |
11 #include "ppapi/cpp/var_array_buffer.h" | |
12 | |
13 #include "javascript_requestor_interface.h" | |
14 #include "volume_reader.h" | |
15 | |
16 // A VolumeReader that reads the content of the volume's archive from | |
17 // JavaScript. All methods including the constructor and destructor should be | |
18 // called from the same thread with the exception of SetBufferAndSignal and | |
19 // ReadErrorSignal which MUST be called from another thread. | |
20 class VolumeReaderJavaScriptStream : public VolumeReader { | |
21 public: | |
22 // archive_size is used by Seek method in order to seek from volume's | |
23 // archive end. | |
24 // requestor is used to request more data from JavaScript. | |
25 VolumeReaderJavaScriptStream(int64_t archive_size, | |
26 JavaScriptRequestorInterface* requestor); | |
27 | |
28 virtual ~VolumeReaderJavaScriptStream(); | |
29 | |
30 // Sets the internal array buffer used for reads and signal the blocked | |
31 // VolumeReaderJavaScriptStream::Read to continue execution. Must be done in | |
32 // a different thread from VolumeReaderJavaScriptStream::Read method. | |
33 // read_offset represents the offset from which VolumeReaderJavaScriptStream | |
34 // requested a chunk read from JavaScriptRequestorInterface. May block for a | |
35 // few cycles in order to synchronize with VolumeReaderJavaScriptStream::Read. | |
36 void SetBufferAndSignal(const pp::VarArrayBuffer& array_buffer, | |
37 int64_t read_offset); | |
38 | |
39 // Signal the blocked VolumeReaderJavaScriptStream::Read to continue execution | |
40 // and return an error code. Must be called from a different thread than | |
41 // VolumeReaderJavaScriptStream::Read. May block for a few cycles in order | |
42 // to synchronize with VolumeReaderJavaScriptStream::Read. | |
43 void ReadErrorSignal(); | |
44 | |
45 // Sets the passphrase and signals the blocked Passphrase() to continue | |
46 // execution. Must be done in a different thread from Passphrase() method. | |
47 // Reporting an error is not supported. Returning an empty string indicates | |
48 // an error. | |
49 void SetPassphraseAndSignal(const std::string& passphrase); | |
50 | |
51 // Signal the blocked VolumeReaderJavaScriptStream::Passphrase to continue | |
52 // execution and return an error code. Must be called from a different thread | |
53 // than VolumeReaderJavaScriptStream::Passphrase. May block for a few cycles | |
54 // in order to synchronize with VolumeReaderJavaScriptStream::Passphrase. | |
55 void PassphraseErrorSignal(); | |
56 | |
57 // See volume_reader.h for description. This method blocks on | |
58 // available_data_cond_. SetBufferAndSignal should unblock it from another | |
59 // thread. | |
60 virtual int64_t Read(int64_t bytes_to_read, const void** destination_buffer); | |
61 | |
62 // See volume_reader.h for description. | |
63 virtual int64_t Skip(int64_t bytes_to_skip); | |
64 | |
65 // See volume_reader.h for description. | |
66 virtual int64_t Seek(int64_t offset, int whence); | |
67 | |
68 // Sets the request Id to be used by the reader. | |
69 void SetRequestId(const std::string& request_id); | |
70 | |
71 // See volume_reader.h for description. The method blocks on | |
72 // available_passphrase_cond_. SetPassphraseAndSignal should unblock it from | |
73 // another thread. | |
74 virtual const char* Passphrase(); | |
75 | |
76 int64_t offset() const { return offset_; } | |
77 | |
78 private: | |
79 // Request a chunk of length number of bytes from JavaScript starting from | |
80 // offset_ member. Should be run within a lock. | |
81 void RequestChunk(int64_t length); | |
82 | |
83 std::string request_id_; // The request id for which the reader was | |
84 // created. | |
85 const int64_t archive_size_; // The archive size. | |
86 | |
87 // A requestor that makes calls to JavaScript to obtain file chunks. | |
88 JavaScriptRequestorInterface* requestor_; | |
89 | |
90 bool available_data_; // Indicates whether any data is available. | |
91 bool read_error_; // Marks an error in reading from JavaScript. | |
92 | |
93 std::string available_passphrase_; // Stores a passphrase from JavaScript. | |
94 bool passphrase_error_; // Marks an error in getting the passphrase. | |
95 | |
96 // Must use POSIX mutexes instead of pp::Lock because there is no pp::Cond. | |
97 // pp::Lock uses POSIX mutexes anyway on Linux, but pp::Lock can also pe used | |
98 // on other operating systems as Windows. For now this is not an issue as this | |
99 // extension is used only on Chromebooks. The shared_state_lock_ is used to | |
100 // protect members which are accessed by more than one thread. | |
101 pthread_mutex_t shared_state_lock_; | |
102 pthread_cond_t available_data_cond_; | |
103 pthread_cond_t available_passphrase_cond_; | |
104 | |
105 int64_t offset_; // The offset from where read should be done. | |
106 int64_t last_read_chunk_offset_; // The offset reached after last call to | |
107 // VolumeReaderJavaScriptStream::Read. | |
108 | |
109 // Two buffers used to store the actual data used by libarchive and the data | |
110 // read ahead. | |
111 pp::VarArrayBuffer first_array_buffer_; | |
112 pp::VarArrayBuffer second_array_buffer_; | |
113 | |
114 // A pointer to first_arrray_buffer_ or second_array_buffer_. This is used in | |
115 // order to avoid an extra copy from the second buffer to the first buffer | |
116 // when data is available for VolumeReaderJavaScriptStream::Read method. | |
117 // It points to the array buffer used for reading ahead when data is received | |
118 // from JavaScript at VolumeReaderJavaScriptStream::SetBufferAndSignal. | |
119 pp::VarArrayBuffer* read_ahead_array_buffer_ptr_; | |
120 }; | |
121 | |
122 #endif // VOLUME_READER_JAVSCRIPT_STREAM_H_ | |
OLD | NEW |