Skip to content

Commit

Permalink
Fix for TTD with fs stat changes. (nodejs#194)
Browse files Browse the repository at this point in the history
Fix for TTD break after change to FS Stats access.

PR-URL: nodejs#194

Signed-off-by: Mark Marron <[email protected]>
Signed-off-by: Hitesh Kanwathirtha <[email protected]>
  • Loading branch information
mrkmarron authored and digitalinfinity committed Mar 22, 2017
1 parent b7a68b5 commit 87ce098
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 20 deletions.
1 change: 1 addition & 0 deletions deps/chakrashim/include/v8.h
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,7 @@ class PersistentBase {

private:
template<class F> friend class Local;
template<class F> friend class Global;
template<class F1, class F2> friend class Persistent;

explicit V8_INLINE PersistentBase(T* val)
Expand Down
14 changes: 8 additions & 6 deletions src/env-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ inline Environment::Environment(IsolateData* isolate_data,
#endif
handle_cleanup_waiting_(0),
http_parser_buffer_(nullptr),
fs_stats_field_array_(nullptr),
fs_stats_field_array_(),
context_(context->GetIsolate(), context) {
// We'll be creating new objects so make sure we've entered the context.
v8::HandleScope handle_scope(isolate());
Expand Down Expand Up @@ -245,6 +245,8 @@ inline Environment::~Environment() {
while (handle_cleanup_waiting_ != 0)
uv_run(event_loop(), UV_RUN_ONCE);

fs_stats_field_array_.Empty();

context()->SetAlignedPointerInEmbedderData(kContextEmbedderDataIndex,
nullptr);
#define V(PropertyName, TypeName) PropertyName ## _.Reset();
Expand Down Expand Up @@ -381,13 +383,13 @@ inline void Environment::set_http_parser_buffer(char* buffer) {
http_parser_buffer_ = buffer;
}

inline double* Environment::fs_stats_field_array() const {
return fs_stats_field_array_;
inline v8::Local<v8::Float64Array> Environment::fs_stats_field_array() const {
return v8::Local<v8::Float64Array>::New(isolate_, fs_stats_field_array_);
}

inline void Environment::set_fs_stats_field_array(double* fields) {
CHECK_EQ(fs_stats_field_array_, nullptr); // Should be set only once.
fs_stats_field_array_ = fields;
inline void Environment::set_fs_stats_field_array(v8::Local<v8::Float64Array> fields) {
CHECK_EQ(fs_stats_field_array_.IsEmpty(), true); // Should be set only once.
fs_stats_field_array_ = v8::Global<v8::Float64Array>::Global(isolate_, fields);
}

inline Environment* Environment::from_cares_timer_handle(uv_timer_t* handle) {
Expand Down
7 changes: 4 additions & 3 deletions src/env.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,8 +491,8 @@ class Environment {
inline char* http_parser_buffer() const;
inline void set_http_parser_buffer(char* buffer);

inline double* fs_stats_field_array() const;
inline void set_fs_stats_field_array(double* fields);
inline v8::Local<v8::Float64Array> fs_stats_field_array() const;
inline void set_fs_stats_field_array(v8::Local<v8::Float64Array> fields);

inline void ThrowError(const char* errmsg);
inline void ThrowTypeError(const char* errmsg);
Expand Down Expand Up @@ -602,7 +602,8 @@ class Environment {

char* http_parser_buffer_;

double* fs_stats_field_array_;
//We depend on the property in fs.js to manage the lifetime appropriately
v8::Global<v8::Float64Array> fs_stats_field_array_;

#define V(PropertyName, TypeName) \
v8::Persistent<TypeName> PropertyName ## _;
Expand Down
29 changes: 20 additions & 9 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,10 @@ static void Close(const FunctionCallbackInfo<Value>& args) {
}


void FillStatsArray(double* fields, const uv_stat_t* s) {
void FillStatsArray(v8::Local<v8::Float64Array> fields_array, const uv_stat_t* s, int offset) {
Local<ArrayBuffer> ab = fields_array->Buffer();
double* fields = static_cast<double*>(ab->GetContents().Data()) + offset;

fields[0] = s->st_dev;
fields[1] = s->st_mode;
fields[2] = s->st_nlink;
Expand Down Expand Up @@ -477,6 +480,12 @@ void FillStatsArray(double* fields, const uv_stat_t* s) {
X(12, ctim)
X(13, birthtim)
#undef X

#if ENABLE_TTD_NODE
if(s_doTTRecord || s_doTTReplay) {
ab->TTDRawBufferModifyNotifySync(offset * sizeof(double), 14 * sizeof(double));
}
#endif
}

// Used to speed up module loading. Returns the contents of the file as
Expand Down Expand Up @@ -1392,18 +1401,20 @@ static void Mkdtemp(const FunctionCallbackInfo<Value>& args) {

void GetStatValues(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
double* fields = env->fs_stats_field_array();
if (fields == nullptr) {
Local<Float64Array> fields = env->fs_stats_field_array();

if (fields.IsEmpty()) {
// stat fields contains twice the number of entries because `fs.StatWatcher`
// needs room to store data for *two* `fs.Stats` instances.
fields = new double[2 * 14];
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(),
new double[2 * 14],
sizeof(double) * 2 * 14);
fields = Float64Array::New(ab, 0, 2 * 14);

env->set_fs_stats_field_array(fields);
}
Local<ArrayBuffer> ab = ArrayBuffer::New(env->isolate(),
fields,
sizeof(double) * 2 * 14);
Local<Float64Array> fields_array = Float64Array::New(ab, 0, 2 * 14);
args.GetReturnValue().Set(fields_array);

args.GetReturnValue().Set(fields);
}

void InitFs(Local<Object> target,
Expand Down
2 changes: 1 addition & 1 deletion src/node_internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ NO_RETURN void FatalError(const char* location, const char* message);

void ProcessEmitWarning(Environment* env, const char* fmt, ...);

void FillStatsArray(double* fields, const uv_stat_t* s);
void FillStatsArray(v8::Local<v8::Float64Array> fields_array, const uv_stat_t* s, int offset = 0);

void SetupProcessObject(Environment* env,
int argc,
Expand Down
2 changes: 1 addition & 1 deletion src/node_stat_watcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
Context::Scope context_scope(env->context());

FillStatsArray(env->fs_stats_field_array(), curr);
FillStatsArray(env->fs_stats_field_array() + 14, prev);
FillStatsArray(env->fs_stats_field_array(), prev, 14);
Local<Value> arg = Integer::New(env->isolate(), status);
wrap->MakeCallback(env->onchange_string(), 1, &arg);
}
Expand Down

0 comments on commit 87ce098

Please sign in to comment.