2013-03-24 2 views
5

मैं एनडीके का उपयोग कर एंड्रॉइड एप्लिकेशन में v8 एम्बेड करने की कोशिश कर रहा हूं।v8 :: लॉकर का उपयोग करने का सही तरीका क्या है, और मुझे इसका उपयोग क्यों करना चाहिए?

मैं एक JNI मॉड्यूल है कि इस (JNI मानचित्रण नहीं दिखाया कोड) तरह दिखता है:

#include <jni.h> 
#include <android/log.h> 

#include <v8.h> 
using namespace v8; 

static jlong getMagicNumber() { 
    HandleScope handle_scope; 
    Persistent<Context> context = Context::New(); 
    Context::Scope context_scope(context); 

    Handle<String> source = String::New("40 + 2"); 

    Handle<Script> script = Script::Compile(source); 
    Handle<Value> result = script->Run(); 

    context.Dispose(); 

    return result->NumberValue(); 
} 

पहली बार मैं getMagicNumber चलाने के लिए, इसे सही ढंग से चलता है और 42 रिटर्न दूसरी बार मैं चलाने का प्रयास यह, यह दुर्घटनाग्रस्त हो जाता है।

विशेष रूप से, इस ASSERT v8 के isolate.h में देखा विफल रहता है:

// Returns the isolate inside which the current thread is running. 
INLINE(static Isolate* Current()) { 
    Isolate* isolate = reinterpret_cast<Isolate*>(
     Thread::GetExistingThreadLocal(isolate_key_)); 
    ASSERT(isolate != NULL); 
    return isolate; 
} 

यह this problem की तरह एक बहुत कुछ है, जो v8::Locker का उपयोग कर पता चलता है "अलग के लिए अनन्य पहुँच" प्राप्त करने के लिए लग रहा है।

10 के शीर्ष पर एक साधारण Locker l; जोड़कर, क्रैश अब नहीं होता है। समस्याएं जो स्वयं को ठीक करती हैं जो आसानी से खुद को तोड़ने लगती हैं जब मैं ध्यान नहीं दे रहा हूं।

मुझे केवल मेरी समस्या को हल करने की सबसे कम समझ है, और मुझे संकलक चेतावनी मिल रही है कि मैं एक बहिष्कृत फैशन में v8::Locker का उपयोग कर रहा हूं। अनुशंसित विधि को v8::Locker के कन्स्ट्रक्टर के तर्क के रूप में प्रदान करने के लिए है, लेकिन मुझे नहीं पता कि मुझे एक पृथक "प्राप्त" करने के लिए कैसे माना जाता है।

अंततः: v8 की वर्तमान स्थिति के अनुसार इस समस्या को हल करने का उचित तरीका क्या है, और क्यों?

उत्तर

6

जैसा कि मैं इसे समझता हूं, एक वी 8 पृथक वी 8 रनटाइम का एक उदाहरण है, एक ढेर, एक कचरा कलेक्टर, और शून्य या अधिक V8 संदर्भों के साथ पूरा होता है। Isolates थ्रेड-सुरक्षित हैं और v8::Locker के माध्यम से सुरक्षित होना चाहिए।

सामान्य में, उपयोग करने के लिए वी 8 आपको पहले एक अलग बनाना चाहिए:, तब

v8::Isolate* isolate = v8::Isolate::New(); 

किसी भी धागे से अलग उपयोग करने के लिए: इस बिंदु पर

v8::Locker locker(isolate); 
v8::Isolate::Scope isolateScope(isolate); 

धागा अलग मालिक है और संदर्भ बनाने के लिए स्वतंत्र है, स्क्रिप्ट निष्पादित करें, आदि

अब, बहुत सरल अनुप्रयोगों के लाभ के लिए, वी 8 एक डिफ़ॉल्ट पृथक प्रदान करता है और लॉकिंग आवश्यकता को आराम देता है, लेकिन आप यदि आप हमेशा एक ही थ्रेड से V8 तक पहुंचते हैं तो इन क्रैच का उपयोग कर सकते हैं। मेरा अनुमान है कि आपका एप्लिकेशन असफल रहा क्योंकि दूसरा कॉल एक अलग थ्रेड से बनाया गया था।

+1

मैं अभी भी पूरी तरह से समझ नहीं पा रहा हूं कि इनमें से प्रत्येक पंक्ति क्या करती है, लेकिन यह मेरे लिए काम करती है। धन्यवाद। – namuol

0

मैं बस अब वी 8 सीख रहा हूँ, लेकिन मैं आपको कॉल करने के लिए की जरूरत है:

v8 :: लॉकर लॉकर (अलग);

यह लॉक ऑब्जेक्ट आवंटित एक स्टैक बनाएगा जो पृथक को किसी अन्य धागे पर इस्तेमाल करने से रोक देगा। जब वर्तमान फ़ंक्शन इस स्टैक ऑब्जेक्ट के विनाशक को लौटाता है तो उसे स्वचालित रूप से अनलॉक करने के कारण स्वचालित रूप से कॉल किया जाएगा।

, जिसे आप कॉल करने की आवश्यकता:

v8 :: पृथक :: स्कोप isolateScope (अलग);

यह इस थ्रेड को चलाने के लिए वर्तमान धागा सेट करता है। अलगाव केवल एक धागे पर इस्तेमाल किया जा सकता है। लॉकर इसे लागू करता है, लेकिन पृथक थ्रेड के लिए पृथक को स्वयं कॉन्फ़िगर करने की आवश्यकता है। यह एक स्टैक आवंटित ऑब्जेक्ट बनाता है जो निर्दिष्ट करता है कि कौन सा पृथक वर्तमान धागे से जुड़ा हुआ है। लॉकर की तरह, जब यह चर गुंजाइश से बाहर हो जाता है (जब वर्तमान फ़ंक्शन लौटाता है) स्कोप विनाशक को पृथक के रूप में पृथक सेट करने के लिए बुलाया जाता है। मेरा मानना ​​है कि इसकी आवश्यकता है क्योंकि कई वी 8 एपीआई कॉलों को एक पृथक के संदर्भ की आवश्यकता है, लेकिन एक पैरामीटर के रूप में नहीं लेते हैं। इसलिए उन्हें एक की आवश्यकता होती है जो वे सीधे एक्सेस कर सकते हैं (शायद प्रति-थ्रेड चर के माध्यम से)।

सभी पृथक :: स्कोप क्लास कन्स्ट्रक्टर में कॉल अलगाव :: एंटर() को कॉल करता है और विनाशक में बाहर निकलें :: बाहर निकलें। इसलिए यदि आप अधिक नियंत्रण चाहते हैं तो आप एंटर()/Exit() स्वयं को कॉल कर सकते हैं।

संबंधित मुद्दे