GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_file.h Lines: 42 50 84.0 %
Date: 2020-05-27 22:15:15 Branches: 2 2 100.0 %

Line Branch Exec Source
1
#ifndef SRC_NODE_FILE_H_
2
#define SRC_NODE_FILE_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "node.h"
7
#include "aliased_buffer.h"
8
#include "stream_base.h"
9
#include <iostream>
10
11
namespace node {
12
namespace fs {
13
14
class FileHandleReadWrap;
15
16
8272
class BindingData : public BaseObject {
17
 public:
18
4568
  explicit BindingData(Environment* env, v8::Local<v8::Object> wrap)
19
4568
      : BaseObject(env, wrap),
20
        stats_field_array(env->isolate(), kFsStatsBufferLength),
21
4568
        stats_field_bigint_array(env->isolate(), kFsStatsBufferLength) {}
22
23
  AliasedFloat64Array stats_field_array;
24
  AliasedBigUint64Array stats_field_bigint_array;
25
26
  std::vector<BaseObjectPtr<FileHandleReadWrap>>
27
      file_handle_read_wrap_freelist;
28
29
  static constexpr FastStringKey binding_data_name { "fs" };
30
31
  void MemoryInfo(MemoryTracker* tracker) const override;
32
19
  SET_SELF_SIZE(BindingData)
33
19
  SET_MEMORY_INFO_NAME(BindingData)
34
};
35
36
// structure used to store state during a complex operation, e.g., mkdirp.
37
9372
class FSContinuationData : public MemoryRetainer {
38
 public:
39
  inline FSContinuationData(uv_fs_t* req, int mode, uv_fs_cb done_cb);
40
41
  inline void PushPath(std::string&& path);
42
  inline void PushPath(const std::string& path);
43
  inline std::string PopPath();
44
  // Used by mkdirp to track the first path created:
45
  inline void MaybeSetFirstPath(const std::string& path);
46
  inline void Done(int result);
47
48
10
  int mode() const { return mode_; }
49
9502
  const std::vector<std::string>& paths() const { return paths_; }
50
223
  const std::string& first_path() const { return first_path_; }
51
52
  void MemoryInfo(MemoryTracker* tracker) const override;
53
  SET_MEMORY_INFO_NAME(FSContinuationData)
54
  SET_SELF_SIZE(FSContinuationData)
55
56
 private:
57
  uv_fs_cb done_cb_;
58
  uv_fs_t* req_;
59
  int mode_;
60
  std::vector<std::string> paths_;
61
  std::string first_path_;
62
};
63
64
class FSReqBase : public ReqWrap<uv_fs_t> {
65
 public:
66
  typedef MaybeStackBuffer<char, 64> FSReqBuffer;
67
68
  inline FSReqBase(BindingData* binding_data,
69
                   v8::Local<v8::Object> req,
70
                   AsyncWrap::ProviderType type,
71
                   bool use_bigint);
72
  ~FSReqBase() override;
73
74
  inline void Init(const char* syscall,
75
                   const char* data,
76
                   size_t len,
77
                   enum encoding encoding);
78
  inline FSReqBuffer& Init(const char* syscall, size_t len,
79
                           enum encoding encoding);
80
81
  virtual void Reject(v8::Local<v8::Value> reject) = 0;
82
  virtual void Resolve(v8::Local<v8::Value> value) = 0;
83
  virtual void ResolveStat(const uv_stat_t* stat) = 0;
84
  virtual void SetReturnValue(
85
      const v8::FunctionCallbackInfo<v8::Value>& args) = 0;
86
87
3987
  const char* syscall() const { return syscall_; }
88
3987
  const char* data() const { return has_data_ ? *buffer_ : nullptr; }
89
6577
  enum encoding encoding() const { return encoding_; }
90
3897
  bool use_bigint() const { return use_bigint_; }
91
92
140
  FSContinuationData* continuation_data() const {
93
140
    return continuation_data_.get();
94
  }
95
14
  void set_continuation_data(std::unique_ptr<FSContinuationData> data) {
96
14
    continuation_data_ = std::move(data);
97
14
  }
98
99
50380
  static FSReqBase* from_req(uv_fs_t* req) {
100
50380
    return static_cast<FSReqBase*>(ReqWrap::from_req(req));
101
  }
102
103
  FSReqBase(const FSReqBase&) = delete;
104
  FSReqBase& operator=(const FSReqBase&) = delete;
105
106
  void MemoryInfo(MemoryTracker* tracker) const override;
107
108
4177
  BindingData* binding_data() { return binding_data_.get(); }
109
110
 private:
111
  std::unique_ptr<FSContinuationData> continuation_data_;
112
  enum encoding encoding_ = UTF8;
113
  bool has_data_ = false;
114
  bool use_bigint_ = false;
115
  const char* syscall_ = nullptr;
116
117
  BaseObjectPtr<BindingData> binding_data_;
118
119
  // Typically, the content of buffer_ is something like a file name, so
120
  // something around 64 bytes should be enough.
121
  FSReqBuffer buffer_;
122
};
123
124
98098
class FSReqCallback final : public FSReqBase {
125
 public:
126
  inline FSReqCallback(BindingData* binding_data,
127
                       v8::Local<v8::Object> req,
128
                       bool use_bigint);
129
130
  void Reject(v8::Local<v8::Value> reject) override;
131
  void Resolve(v8::Local<v8::Value> value) override;
132
  void ResolveStat(const uv_stat_t* stat) override;
133
  void SetReturnValue(const v8::FunctionCallbackInfo<v8::Value>& args) override;
134
135
1
  SET_MEMORY_INFO_NAME(FSReqCallback)
136
1
  SET_SELF_SIZE(FSReqCallback)
137
138
  FSReqCallback(const FSReqCallback&) = delete;
139
  FSReqCallback& operator=(const FSReqCallback&) = delete;
140
};
141
142
template <typename NativeT, typename V8T>
143
void FillStatsArray(AliasedBufferBase<NativeT, V8T>* fields,
144
                    const uv_stat_t* s,
145
                    const size_t offset = 0);
146
147
inline v8::Local<v8::Value> FillGlobalStatsArray(BindingData* binding_data,
148
                                                 const bool use_bigint,
149
                                                 const uv_stat_t* s,
150
                                                 const bool second = false);
151
152
template <typename AliasedBufferT>
153
class FSReqPromise final : public FSReqBase {
154
 public:
155
  static inline FSReqPromise* New(BindingData* binding_data,
156
                                  bool use_bigint);
157
  inline ~FSReqPromise() override;
158
159
  inline void Reject(v8::Local<v8::Value> reject) override;
160
  inline void Resolve(v8::Local<v8::Value> value) override;
161
  inline void ResolveStat(const uv_stat_t* stat) override;
162
  inline void SetReturnValue(
163
      const v8::FunctionCallbackInfo<v8::Value>& args) override;
164
  inline void MemoryInfo(MemoryTracker* tracker) const override;
165
166
1
  SET_MEMORY_INFO_NAME(FSReqPromise)
167
1
  SET_SELF_SIZE(FSReqPromise)
168
169
  FSReqPromise(const FSReqPromise&) = delete;
170
  FSReqPromise& operator=(const FSReqPromise&) = delete;
171
  FSReqPromise(const FSReqPromise&&) = delete;
172
  FSReqPromise& operator=(const FSReqPromise&&) = delete;
173
174
 private:
175
  inline FSReqPromise(BindingData* binding_data,
176
                      v8::Local<v8::Object> obj,
177
                      bool use_bigint);
178
179
  bool finished_ = false;
180
  AliasedBufferT stats_field_array_;
181
};
182
183
class FSReqAfterScope final {
184
 public:
185
  FSReqAfterScope(FSReqBase* wrap, uv_fs_t* req);
186
  ~FSReqAfterScope();
187
  void Clear();
188
189
  bool Proceed();
190
191
  void Reject(uv_fs_t* req);
192
193
  FSReqAfterScope(const FSReqAfterScope&) = delete;
194
  FSReqAfterScope& operator=(const FSReqAfterScope&) = delete;
195
  FSReqAfterScope(const FSReqAfterScope&&) = delete;
196
  FSReqAfterScope& operator=(const FSReqAfterScope&&) = delete;
197
198
 private:
199
  BaseObjectPtr<FSReqBase> wrap_;
200
  uv_fs_t* req_ = nullptr;
201
  v8::HandleScope handle_scope_;
202
  v8::Context::Scope context_scope_;
203
};
204
205
class FileHandle;
206
207
// A request wrap specifically for uv_fs_read()s scheduled for reading
208
// from a FileHandle.
209
class FileHandleReadWrap final : public ReqWrap<uv_fs_t> {
210
 public:
211
  FileHandleReadWrap(FileHandle* handle, v8::Local<v8::Object> obj);
212
  ~FileHandleReadWrap() override;
213
214
207
  static inline FileHandleReadWrap* from_req(uv_fs_t* req) {
215
207
    return static_cast<FileHandleReadWrap*>(ReqWrap::from_req(req));
216
  }
217
218
  void MemoryInfo(MemoryTracker* tracker) const override;
219
  SET_MEMORY_INFO_NAME(FileHandleReadWrap)
220
  SET_SELF_SIZE(FileHandleReadWrap)
221
222
 private:
223
  FileHandle* file_handle_;
224
  uv_buf_t buffer_;
225
226
  friend class FileHandle;
227
};
228
229
// A wrapper for a file descriptor that will automatically close the fd when
230
// the object is garbage collected
231
class FileHandle final : public AsyncWrap, public StreamBase {
232
 public:
233
  static FileHandle* New(BindingData* binding_data,
234
                         int fd,
235
                         v8::Local<v8::Object> obj = v8::Local<v8::Object>());
236
  ~FileHandle() override;
237
238
  static void New(const v8::FunctionCallbackInfo<v8::Value>& args);
239
240
281
  int GetFD() override { return fd_; }
241
242
  // Will asynchronously close the FD and return a Promise that will
243
  // be resolved once closing is complete.
244
  static void Close(const v8::FunctionCallbackInfo<v8::Value>& args);
245
246
  // Releases ownership of the FD.
247
  static void ReleaseFD(const v8::FunctionCallbackInfo<v8::Value>& args);
248
249
  // StreamBase interface:
250
  int ReadStart() override;
251
  int ReadStop() override;
252
253
493
  bool IsAlive() override { return !closed_; }
254
212
  bool IsClosing() override { return closing_; }
255
339
  AsyncWrap* GetAsyncWrap() override { return this; }
256
257
  // In the case of file streams, shutting down corresponds to closing.
258
  ShutdownWrap* CreateShutdownWrap(v8::Local<v8::Object> object) override;
259
  int DoShutdown(ShutdownWrap* req_wrap) override;
260
261
  int DoWrite(WriteWrap* w,
262
              uv_buf_t* bufs,
263
              size_t count,
264
              uv_stream_t* send_handle) override;
265
266
  void MemoryInfo(MemoryTracker* tracker) const override;
267
268
  SET_MEMORY_INFO_NAME(FileHandle)
269
  SET_SELF_SIZE(FileHandle)
270
271
  FileHandle(const FileHandle&) = delete;
272
  FileHandle& operator=(const FileHandle&) = delete;
273
  FileHandle(const FileHandle&&) = delete;
274
  FileHandle& operator=(const FileHandle&&) = delete;
275
276
 private:
277
  FileHandle(BindingData* binding_data, v8::Local<v8::Object> obj, int fd);
278
279
  // Synchronous close that emits a warning
280
  void Close();
281
  void AfterClose();
282
283
  class CloseReq final : public ReqWrap<uv_fs_t> {
284
   public:
285
    CloseReq(Environment* env,
286
             v8::Local<v8::Object> obj,
287
             v8::Local<v8::Promise> promise,
288
             v8::Local<v8::Value> ref);
289
    ~CloseReq() override;
290
291
    FileHandle* file_handle();
292
293
    void MemoryInfo(MemoryTracker* tracker) const override;
294
295
    SET_MEMORY_INFO_NAME(CloseReq)
296
    SET_SELF_SIZE(CloseReq)
297
298
    void Resolve();
299
300
    void Reject(v8::Local<v8::Value> reason);
301
302
280
    static CloseReq* from_req(uv_fs_t* req) {
303
280
      return static_cast<CloseReq*>(ReqWrap::from_req(req));
304
    }
305
306
    CloseReq(const CloseReq&) = delete;
307
    CloseReq& operator=(const CloseReq&) = delete;
308
    CloseReq(const CloseReq&&) = delete;
309
    CloseReq& operator=(const CloseReq&&) = delete;
310
311
   private:
312
    v8::Global<v8::Promise> promise_{};
313
    v8::Global<v8::Value> ref_{};
314
  };
315
316
  // Asynchronous close
317
  v8::MaybeLocal<v8::Promise> ClosePromise();
318
319
  int fd_;
320
  bool closing_ = false;
321
  bool closed_ = false;
322
  int64_t read_offset_ = -1;
323
  int64_t read_length_ = -1;
324
325
  bool reading_ = false;
326
  BaseObjectPtr<FileHandleReadWrap> current_read_;
327
328
  BaseObjectPtr<BindingData> binding_data_;
329
};
330
331
int MKDirpSync(uv_loop_t* loop,
332
               uv_fs_t* req,
333
               const std::string& path,
334
               int mode,
335
               uv_fs_cb cb = nullptr);
336
337
class FSReqWrapSync {
338
 public:
339
302232
  FSReqWrapSync() = default;
340
302232
  ~FSReqWrapSync() { uv_fs_req_cleanup(&req); }
341
  uv_fs_t req;
342
343
24069
  FSContinuationData* continuation_data() const {
344
24069
    return continuation_data_.get();
345
  }
346
4672
  void set_continuation_data(std::unique_ptr<FSContinuationData> data) {
347
4672
    continuation_data_ = std::move(data);
348
4672
  }
349
350
  FSReqWrapSync(const FSReqWrapSync&) = delete;
351
  FSReqWrapSync& operator=(const FSReqWrapSync&) = delete;
352
353
 private:
354
  std::unique_ptr<FSContinuationData> continuation_data_;
355
};
356
357
// TODO(addaleax): Currently, callers check the return value and assume
358
// that nullptr indicates a synchronous call, rather than a failure.
359
// Failure conditions should be disambiguated and handled appropriately.
360
inline FSReqBase* GetReqWrap(const v8::FunctionCallbackInfo<v8::Value>& args,
361
                             int index,
362
                             bool use_bigint = false);
363
364
// Returns nullptr if the operation fails from the start.
365
template <typename Func, typename... Args>
366
inline FSReqBase* AsyncDestCall(Environment* env, FSReqBase* req_wrap,
367
                                const v8::FunctionCallbackInfo<v8::Value>& args,
368
                                const char* syscall, const char* dest,
369
                                size_t len, enum encoding enc, uv_fs_cb after,
370
                                Func fn, Args... fn_args);
371
372
// Returns nullptr if the operation fails from the start.
373
template <typename Func, typename... Args>
374
inline FSReqBase* AsyncCall(Environment* env,
375
                            FSReqBase* req_wrap,
376
                            const v8::FunctionCallbackInfo<v8::Value>& args,
377
                            const char* syscall, enum encoding enc,
378
                            uv_fs_cb after, Func fn, Args... fn_args);
379
380
// Template counterpart of SYNC_CALL, except that it only puts
381
// the error number and the syscall in the context instead of
382
// creating an error in the C++ land.
383
// ctx must be checked using value->IsObject() before being passed.
384
template <typename Func, typename... Args>
385
inline int SyncCall(Environment* env, v8::Local<v8::Value> ctx,
386
                    FSReqWrapSync* req_wrap, const char* syscall,
387
                    Func fn, Args... args);
388
389
}  // namespace fs
390
391
}  // namespace node
392
393
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
394
395
#endif  // SRC_NODE_FILE_H_