2013-03-24 39 views
5

Tôi đang cố gắng nhúng v8 vào ứng dụng Android bằng NDK.Cách chính xác để sử dụng v8 :: Locker là gì và tại sao tôi phải sử dụng nó?

Tôi có một mô-đun JNI trông giống như thế này (mã lập bản đồ JNI không hiển thị):

#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(); 
} 

Lần đầu tiên tôi chạy getMagicNumber, nó chạy một cách chính xác và trả về 42. Lần thứ hai tôi cố gắng chạy nó, nó bị treo.

Cụ thể, ASSERT này thấy trong v8 của isolate.h thất bại:

// 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; 
} 

Nghe có vẻ rất giống this problem, mà cho thấy sử dụng v8::Locker để có được "độc quyền truy cập đến cô lập".

Bằng cách thêm Locker l; đơn giản lên đầu getMagicNumber, sự cố không còn xảy ra nữa. Các vấn đề khắc phục bản thân dễ dàng có xu hướng phá vỡ bản thân khi tôi không chú ý.

Tôi chỉ có hiểu biết nhiều nhất về lý do tại sao điều này khắc phục sự cố của tôi và tôi nhận được cảnh báo trình biên dịch mà tôi đang sử dụng v8::Locker theo cách không được chấp nhận. Phương pháp được đề xuất là cung cấp phương thức này với một số v8::Isolate làm đối số cho hàm tạo của v8::Locker, nhưng tôi không biết làm cách nào để "có được" một cách ly.

Cuối cùng: Cách thích hợp để giải quyết vấn đề này theo trạng thái hiện tại của v8 là gì và lý do tại sao?

Trả lời

6

Như tôi đã hiểu, V8 cách ly là một ví dụ về thời gian chạy V8, hoàn chỉnh với một đống, bộ thu gom rác và không có nhiều bối cảnh V8. Các cô lập là không phải là an toàn chỉ và phải được bảo vệ qua v8::Locker.

Nói chung, sử dụng động cơ V8 đầu tiên bạn phải tạo một cô lập:

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

Sau đó, để sử dụng cô lập từ bất kỳ chủ đề:

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

Tại thời điểm này các chủ đề sở hữu cô lập và là miễn phí để tạo ngữ cảnh, thực thi tập lệnh, v.v.

Bây giờ, vì lợi ích của các ứng dụng rất đơn giản, V8 cung cấp cách ly mặc định và làm giãn yêu cầu khóa, nhưng bạn chỉ có thể sử dụng các nạng này nếu bạn luôn truy cập V8 từ cùng một chuỗi. Tôi đoán là ứng dụng của bạn không thành công vì cuộc gọi thứ hai được tạo từ một chuỗi khác.

+1

Tôi vẫn chưa hiểu đầy đủ những gì từng dòng đó thực hiện, nhưng điều này hiệu quả với tôi. Cảm ơn. – namuol

0

Tôi chỉ đang học V8 ngay bây giờ, nhưng tôi nghĩ bạn cần gọi:

v8 :: Locker locker (isolate);

Thao tác này sẽ tạo đối tượng Locker được cấp phát ngăn xếp sẽ chặn Phân cách không được sử dụng trên một chuỗi khác. Khi hàm hiện tại trả về destructor của đối tượng ngăn xếp này sẽ được gọi tự động khiến cho Isolate được mở khóa.

Bạn cần gọi:

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

Điều này đặt chuỗi hiện tại để chạy cách ly này. Cô lập chỉ có thể được sử dụng trên một sợi. Locker thực thi điều này, nhưng chính Isolate cần được cấu hình cho luồng hiện tại. Điều này tạo ra một đối tượng được cấp phát ngăn xếp xác định Isolate nào được kết hợp với luồng hiện tại. Cũng giống như Locker, khi biến này nằm ngoài phạm vi (khi hàm trả về hiện hành), hàm hủy phạm vi được gọi để bỏ đặt Isolate làm mặc định. Tôi tin rằng điều này là cần thiết vì nhiều cuộc gọi API V8 cần tham chiếu đến một Cô lập, nhưng không lấy tham chiếu làm tham số. Vì vậy, họ cần một người mà họ có thể truy cập trực tiếp (có thể thông qua các biến cho mỗi luồng).

Tất cả các Isolate :: Phạm vi lớp học không gọi là cô lập :: Enter() trong constructor và cô lập :: Exit() trong destructor. Vì vậy, nếu bạn muốn kiểm soát nhiều hơn, bạn có thể gọi Enter()/Exit().

Các vấn đề liên quan