Skip to content

FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place #334

Closed
@ashishchandr70

Description

@ashishchandr70

Hi,

I am using threads.js for a multi-player game. The main thread spawns two separate workers who each execute the same function.

The two worker threads go ahead and do what they need to do and I await a websocket message to resolve a promise which indicates that the processing is complete.

However, when I call Thread.terminate, I immediately get the following error:

FATAL ERROR: HandleScope::HandleScope Entering the V8 API without proper locking in place
 1: 0xa18150 node::Abort() [node]
 2: 0xa1855c node::OnFatalError(char const*, char const*) [node]
 3: 0xb9638a v8::Utils::ReportApiFailure(char const*, char const*) [node]
 4: 0xb9792e v8::HandleScope::HandleScope(v8::Isolate*) [node]
 5: 0xacd89e node::worker::Worker::JoinThread() [node]
 6: 0x9baed0 node::Environment::stop_sub_worker_contexts() [node]
 7: 0x9bafe0 node::Environment::Stop() [node]
 8: 0x9e5e79 node::Stop(node::Environment*) [node]
 9: 0xad2926 node::worker::Worker::StopThread(v8::FunctionCallbackInfo<v8::Value> const&) [node]
10: 0xc02529  [node]
11: 0xc04317 v8::internal::Builtin_HandleApiCall(int, unsigned long*, v8::internal::Isolate*) [node]
12: 0x1409e59  [node]
Aborted (core dumped)
npm ERR! Test failed.  See above for more details.
Waiting for the debugger to disconnect...

Here is my code from the master (main thread):

try {
            let battleMessage = await new Promise(async (resolve, reject) => {
                const ws = new WSClient(WebSocket, `${mockurl.replace('http', 'ws')}/ws`, ['BattleCompleted', 'BattleCreated']);

                ws.on('msg', async (message) => {
                    console.log(`WS Message:`, message);
                    if (message.subject === 'BattleCompleted') {
                       resolve(message);
                    }
                });

                playerThread1 = await spawn(new Worker(`../scripts/player-setup`));
                playerThread2 = await spawn(new Worker(`../scripts/player-setup`));

                Thread.events(playerThread1).subscribe(event => {
                    console.log(`playerThread1 event: ${JSON.stringify(event,null,4)}`);
                    switch (event.type) {
                    case 'message':
                        if (event.data.type === 'result' && event.data.complete === true) {
                            console.log(`playerThread1 has completed processing`);
                        }
                        else if(event.data.type === 'uncaughtError') console.error(`Error from playerThread1: ${JSON.stringify(event.data.error,null,4)}`);
                        break;
                    default:
                        break;
    
    
                    }
                });
                Thread.events(playerThread2).subscribe(event => {
                    console.log(`playerThread2 event: ${JSON.stringify(event,null,4)}`);
                    switch (event.type) {
                    case 'message':
                        if (event.data.type === 'result' && event.data.complete === true) {
                            console.log(`playerThread2 has completed processing`);
                        }
                        else if(event.data.type === 'uncaughtError') console.error(`Error from playerThread2: ${JSON.stringify(event.data.error,null,4)}`);
                        break;
                    default:
                        break;
    
    
                    }
                }); 
                
                let player1 = await playerThread1.executePvPBattle(Loaded.location, { playerName: 'SuperElf' });
                let player2 = await playerThread2.executePvPBattle(Loaded.location, {
                    playerName: 'Frodo'
                });                
            });

            let winner = JSON.parse(battleMessage.payload);
            console.log(`Winner: ${winner}`);

        }
        catch (e) {
            console.error(`Error received ${e}`);
        }
        finally {
            await Thread.terminate(playerThread1);
            await Thread.terminate(playerThread2);
        }

Everything works normally and I get the console.log for the winner. However, the moment it tries to execute await Thread.terminate(playerThread1); I get the V8 API error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions