Changeset 20083


Ignore:
Timestamp:
04/19/21 11:29:13 (4 years ago)
Author:
tbretz
Message:
Replaced my own PersistentCopy by UniquePersistent, repaired Thread object (with the drawback that individual threads can not be killed anymore as everything is executed effectively in a single thread. So threads can execute code interleaved but not really in a parallel, like a singel core cpu.
Location:
trunk/FACT++/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/FACT++/src/InterpreterV8-4.cc

    r20024 r20083  
    222222}
    223223
    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 
     224void 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);
    246236    const HandleScope handle_scope(isolate);
    247237
    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();
    251244
    252245    const bool rc = ms==0 || !ExecuteInternal("v8.sleep("+to_string(ms)+");").IsEmpty();
     
    254247    {
    255248        if (_this.IsEmpty())
    256             func->Call(func, 0, NULL);
     249            Handle<Function>::Cast(fun)->Call(fun->CreationContext(), fun, 0, NULL).IsEmpty();
    257250        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();
    271258}
    272259
     
    307294    }
    308295
    309     //*NEW or OLD?*
    310     //if (!args.IsConstructCall())
    311     //    return Constructor(args);
    312 /*
    313296    const HandleScope handle_scope(isolate);
    314297
    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;
    319301    if (args.Length()==3)
    320         _this = Persistent<Object>::New(args[2]->ToObject());
     302        _this = UniquePersistent<Object>(isolate, args[2]->ToObject());
    321303
    322304    const uint32_t ms = args[0]->Uint32Value();
    323305
    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    /*
    326309    {
    327310        // Allow the thread to lock, so we can get the thread id.
     
    330313            usleep(1);
    331314    }
    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    */
    337321}
    338322
     
    19461930
    19471931    if (value->IsFunction())
    1948         fStateCallbacks[server] = PersistentCopy<Object>(isolate, value->ToObject());
     1932        fStateCallbacks[server] = UniquePersistent<Object>(isolate, value->ToObject());
    19491933}
    19501934
     
    20412025
    20422026    // 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());
    20442028}
    20452029
     
    22042188        self->Set(String::NewFromUtf8(isolate, "onchange"), args[1]);
    22052189
    2206     fReverseMap[*str] = PersistentCopy<Object>(isolate, self);
     2190    fReverseMap[*str] = UniquePersistent<Object>(isolate, self);
    22072191
    22082192    void *ptr = JsSubscribe(*str);
     
    29322916        // Unlocking is necessary for the preemption to work
    29332917        const Unlocker global_unlock(isolate);
    2934 
    29352918        const string buffer = Tools::Trim(Readline::StaticPrompt(command.empty() ? "JS> " : " \\> "));
    29362919        if (buffer==".q")
     
    29712954        if (!HandleException(exception, "console"))
    29722955            lout << endl;
    2973 
    2974         // Stop all other threads
    2975         for (auto it=fThreadIsolates.begin(); it!=fThreadIsolates.end(); it++)
    2976             (*it)->TerminateExecution();
    2977 
    2978         // Allow the java scripts (threads) to run and hence to terminate
    2979         const Unlocker unlock(isolate);
    2980 
    2981         // Wait until all threads are terminated
    2982         while (!fThreadIsolates.empty())
    2983             usleep(1000);
    29842956
    29852957        // command has been executed, collect new command
     
    32333205        Handle<FunctionTemplate> thread = FunctionTemplate::New(isolate, WrapThread);
    32343206        thread->SetClassName(String::NewFromUtf8(isolate, "Thread"));
    3235 #if 0
    32363207        global->Set(String::NewFromUtf8(isolate, "Thread"), thread, ReadOnly);
    3237 #endif
    32383208
    32393209        Handle<FunctionTemplate> file = FunctionTemplate::New(isolate, WrapFile);
     
    33783348
    33793349            //        Locker::StopPreemption();
    3380 /*OLD*/
    3381             // Stop all other threads
    3382             //        for (auto it=fThreadIsolates.begin(); it!=fThreadIsolates.end(); it++)
    3383             //            (*it)->TerminateExecution();
    3384             //        fThreadIsolates.clear();
    33853350        }
    33863351
     
    34003365    // So we have to unlock (manual preemtion) so that they get
    34013366    // 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
    34133375    fInterruptCallback.Reset();
    34143376
     
    34163378    fStateCallbacks.clear();
    34173379
    3418     // ... and from the onchange callbacks
     3380    // ... and from the onchange callbacks       
    34193381    fReverseMap.clear();
    34203382
  • trunk/FACT++/src/InterpreterV8-4.h

    r20047 r20083  
    3232class InterpreterV8
    3333{
    34     template<class T>
    35         using PersistentCopy = v8::Persistent<T, v8::CopyablePersistentTraits<T>>;
    36 
    3734    template<class T, class S>
    38        using PersistentMap = std::map<T, PersistentCopy<S>>;
     35       using PersistentMap = std::map<T, v8::UniquePersistent<S>>;
    3936
    4037    static InterpreterV8 *This;
     
    4441    // the thread forcefully from 'the outside'
    4542    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
    4945    // the JavaScript object corrsponding to the
    5046    // service name (for checking of an .onchange
     
    6258
    6359    // Interrupt handler
    64     PersistentCopy<v8::Object> fInterruptCallback;
     60    v8::UniquePersistent<v8::Object> fInterruptCallback;
    6561
    6662    static v8::Handle<v8::FunctionTemplate> fTemplateLocal;
     
    8177    v8::Handle<v8::Value> ExecuteInternal(const std::string &code);
    8278
    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);
    8480
    8581    std::vector<std::string> ValueToArray(const v8::Handle<v8::Value> &val, bool only=true);
    8682
    87     //typedef v8::internal::Arguments FactArguments;
    88     //typedef v8::FunctionCallback FactArguments;
    8983    typedef v8::FunctionCallbackInfo<v8::Value> FactArguments;
    9084
Note: See TracChangeset for help on using the changeset viewer.