- Timestamp:
- 04/19/21 11:29:13 (4 years ago)
- Location:
- trunk/FACT++/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/FACT++/src/InterpreterV8-4.cc
r20024 r20083 222 222 } 223 223 224 void InterpreterV8::Thread(int &id, Persistent<Object> _this, Persistent<Function> func, uint32_t ms) 225 { 226 /* 227 Isolate *isolate = Isolate::GetCurrent(); 228 229 const Locker lock(isolate); 230 231 if (fThreadId<0) 232 { 233 id = -1; 234 return; 235 } 236 237 // Warning: As soon as id is set, the parent of this thread might terminate 238 // and hance the reference to id does not exist anymore. So, id 239 // is just a kind of return value and must not be used at all 240 // otherwise. 241 242 const int id_local = V8::GetCurrentThreadId(); 243 id = id_local; 244 fThreadIds.insert(id_local); 245 224 void InterpreterV8::Thread(int &id, v8::UniquePersistent<Object> &_this, v8::UniquePersistent<v8::Object> &func, uint32_t ms) 225 { 226 Isolate *isolate = fMainThread; 227 if (!isolate) 228 return; 229 230 // We want to run as an interrupt in the main thread 231 const Locker locker(isolate); 232 if (!fMainThread) 233 return; 234 235 const Isolate::Scope isolate_scope(isolate); 246 236 const HandleScope handle_scope(isolate); 247 237 248 func->CreationContext()->Enter(); 249 250 TryCatch exception; 238 Handle<Object> fun = func.Get(isolate); 239 const Context::Scope scope(fun->CreationContext()); 240 241 TryCatch exception(isolate); 242 243 fun->CreationContext()->Enter(); 251 244 252 245 const bool rc = ms==0 || !ExecuteInternal("v8.sleep("+to_string(ms)+");").IsEmpty(); … … 254 247 { 255 248 if (_this.IsEmpty()) 256 func->Call(func, 0, NULL);249 Handle<Function>::Cast(fun)->Call(fun->CreationContext(), fun, 0, NULL).IsEmpty(); 257 250 else 258 func->Call(_this, 0, NULL); 259 } 260 261 func.Dispose(); 262 _this.Dispose(); 263 264 fThreadIds.erase(id_local); 265 266 if (!HandleException(exception, "thread")) 267 V8::TerminateExecution(isolate); 268 269 func->CreationContext()->Exit(); 270 */ 251 Handle<Function>::Cast(fun)->Call(fun->CreationContext(), _this.Get(isolate), 0, NULL).IsEmpty(); 252 } 253 254 if (!HandleException(exception, "Thread")) 255 isolate->AddBeforeCallEnteredCallback(TerminateExecution); 256 257 fun->CreationContext()->Exit(); 271 258 } 272 259 … … 307 294 } 308 295 309 //*NEW or OLD?*310 //if (!args.IsConstructCall())311 // return Constructor(args);312 /*313 296 const HandleScope handle_scope(isolate); 314 297 315 Handle<Function> handle = Handle<Function>::Cast(args[1]); 316 317 Persistent<Function> func = Persistent<Function>::New(isolate, handle); 318 Persistent<Object> _this; 298 UniquePersistent<Object> func = UniquePersistent<Object>(isolate, args[1]->ToObject()); 299 300 UniquePersistent<Object> _this; 319 301 if (args.Length()==3) 320 _this = Persistent<Object>::New(args[2]->ToObject());302 _this = UniquePersistent<Object>(isolate, args[2]->ToObject()); 321 303 322 304 const uint32_t ms = args[0]->Uint32Value(); 323 305 324 int id=-2; 325 fThreads.push_back(thread(bind(&InterpreterV8::Thread, this, ref(id), _this, func, ms))); 306 //int id=__id; 307 fThreads.push_back(thread(bind(&InterpreterV8::Thread, this, ref(id), std::move(_this), std::move(func), ms))); 308 /* 326 309 { 327 310 // Allow the thread to lock, so we can get the thread id. … … 330 313 usleep(1); 331 314 } 332 */ 333 // Handle<Object> self = args.This(); 334 // self->Set(String::NewFromUtf8(isolate, "id"), Integer::NewFromUnsigned(isolate, id)/*, ReadOnly*/); 335 // self->Set(String::NewFromUtf8(isolate, "kill"), FunctionTemplate::New(isolate, WrapKill)->GetFunction()/*, ReadOnly*/); 336 // args.GetReturnValue().Set(self); 315 316 Handle<Object> self = args.This(); 317 self->Set(String::NewFromUtf8(isolate, "id"), Integer::NewFromUnsigned(isolate, id)); 318 self->Set(String::NewFromUtf8(isolate, "kill"), FunctionTemplate::New(isolate, WrapKill)->GetFunction()); 319 args.GetReturnValue().Set(self); 320 */ 337 321 } 338 322 … … 1946 1930 1947 1931 if (value->IsFunction()) 1948 fStateCallbacks[server] = PersistentCopy<Object>(isolate, value->ToObject());1932 fStateCallbacks[server] = UniquePersistent<Object>(isolate, value->ToObject()); 1949 1933 } 1950 1934 … … 2041 2025 2042 2026 // Returns the value if the setter intercepts the request. Otherwise, returns an empty handle. 2043 fInterruptCallback = PersistentCopy<Object>(isolate, args[0]->ToObject());2027 fInterruptCallback = UniquePersistent<Object>(isolate, args[0]->ToObject()); 2044 2028 } 2045 2029 … … 2204 2188 self->Set(String::NewFromUtf8(isolate, "onchange"), args[1]); 2205 2189 2206 fReverseMap[*str] = PersistentCopy<Object>(isolate, self);2190 fReverseMap[*str] = UniquePersistent<Object>(isolate, self); 2207 2191 2208 2192 void *ptr = JsSubscribe(*str); … … 2932 2916 // Unlocking is necessary for the preemption to work 2933 2917 const Unlocker global_unlock(isolate); 2934 2935 2918 const string buffer = Tools::Trim(Readline::StaticPrompt(command.empty() ? "JS> " : " \\> ")); 2936 2919 if (buffer==".q") … … 2971 2954 if (!HandleException(exception, "console")) 2972 2955 lout << endl; 2973 2974 // Stop all other threads2975 for (auto it=fThreadIsolates.begin(); it!=fThreadIsolates.end(); it++)2976 (*it)->TerminateExecution();2977 2978 // Allow the java scripts (threads) to run and hence to terminate2979 const Unlocker unlock(isolate);2980 2981 // Wait until all threads are terminated2982 while (!fThreadIsolates.empty())2983 usleep(1000);2984 2956 2985 2957 // command has been executed, collect new command … … 3233 3205 Handle<FunctionTemplate> thread = FunctionTemplate::New(isolate, WrapThread); 3234 3206 thread->SetClassName(String::NewFromUtf8(isolate, "Thread")); 3235 #if 03236 3207 global->Set(String::NewFromUtf8(isolate, "Thread"), thread, ReadOnly); 3237 #endif3238 3208 3239 3209 Handle<FunctionTemplate> file = FunctionTemplate::New(isolate, WrapFile); … … 3378 3348 3379 3349 // Locker::StopPreemption(); 3380 /*OLD*/3381 // Stop all other threads3382 // for (auto it=fThreadIsolates.begin(); it!=fThreadIsolates.end(); it++)3383 // (*it)->TerminateExecution();3384 // fThreadIsolates.clear();3385 3350 } 3386 3351 … … 3400 3365 // So we have to unlock (manual preemtion) so that they get 3401 3366 // the signal to terminate. 3402 /* 3403 { 3404 const Unlocker unlock(isolate); 3405 3406 for (auto it=fThreads.begin(); it!=fThreads.end(); it++) 3407 { 3408 it->join(); 3409 fThreads.clear(); 3410 }*/ 3411 3412 // Now we can dispose the persistent interrupt handler 3367 //{ 3368 // const Unlocker unlock(isolate); 3369 for (auto it=fThreads.begin(); it!=fThreads.end(); it++) 3370 it->join(); 3371 fThreads.clear(); 3372 //} 3373 3374 // Now we can dispose the persistent interrupt handlers 3413 3375 fInterruptCallback.Reset(); 3414 3376 … … 3416 3378 fStateCallbacks.clear(); 3417 3379 3418 // ... and from the onchange callbacks 3380 // ... and from the onchange callbacks 3419 3381 fReverseMap.clear(); 3420 3382 -
trunk/FACT++/src/InterpreterV8-4.h
r20047 r20083 32 32 class InterpreterV8 33 33 { 34 template<class T>35 using PersistentCopy = v8::Persistent<T, v8::CopyablePersistentTraits<T>>;36 37 34 template<class T, class S> 38 using PersistentMap = std::map<T, PersistentCopy<S>>;35 using PersistentMap = std::map<T, v8::UniquePersistent<S>>; 39 36 40 37 static InterpreterV8 *This; … … 44 41 // the thread forcefully from 'the outside' 45 42 v8::Isolate *fMainThread; 46 std::set<v8::Isolate*> fThreadIsolates; 47 48 // A loookup table which allows to indentify the 43 44 // A loookup table which allows to indentify 49 45 // the JavaScript object corrsponding to the 50 46 // service name (for checking of an .onchange … … 62 58 63 59 // Interrupt handler 64 PersistentCopy<v8::Object> fInterruptCallback;60 v8::UniquePersistent<v8::Object> fInterruptCallback; 65 61 66 62 static v8::Handle<v8::FunctionTemplate> fTemplateLocal; … … 81 77 v8::Handle<v8::Value> ExecuteInternal(const std::string &code); 82 78 83 void Thread(int &id, v8:: Persistent<v8::Object> _this, v8::Persistent<v8::Function>func, uint32_t ms);79 void Thread(int &id, v8::UniquePersistent<v8::Object> &_this, v8::UniquePersistent<v8::Object> &func, uint32_t ms); 84 80 85 81 std::vector<std::string> ValueToArray(const v8::Handle<v8::Value> &val, bool only=true); 86 82 87 //typedef v8::internal::Arguments FactArguments;88 //typedef v8::FunctionCallback FactArguments;89 83 typedef v8::FunctionCallbackInfo<v8::Value> FactArguments; 90 84
Note:
See TracChangeset
for help on using the changeset viewer.