Ikrom
Ikrom

Reputation: 5123

JavaScript deadlock

Here I saw JavaScript deadlocks and this code:

var loop = true,
block = setTimeout(function(){loop = false}, 1);
while(loop);

It's definitely infinite loop and causes to browser freezing. It's said that deadlock is created when one operation wait another one to be executed and vice-versa.
My question is, except that, what kind of situations deadlock occurs and the ways to avoid them?

Upvotes: 4

Views: 8259

Answers (2)

Doug Coburn
Doug Coburn

Reputation: 2575

Javascript can deadlock, parallel execution is not a necessary condition of deadlock. the javascript VM is single threaded, but it has a concurrent execution paradigm so the Coffman conditions can be met:

Here is an example:

function makeFuture() {
  let resolve;
  let reject;
  let promise = new Promise((d, e) => {
    resolve = d;
    reject = e;
  });
  return [promise, resolve, reject];
}

class Lock {
  constructor() {
    this.q = [];
    this.running = false;
  }
  async runQueue() {
    if (this.running) return;
    this.running = true;
    while (this.q.length > 0) {
      const { asyncFunction, resolve, reject } = this.q.shift();
      try {
        let result = await asyncFunction();
        resolve(await asyncFunction());
      } catch (error) {
        reject(error);
      }
    }
    this.running = false;
  }
  runTask(asyncFunction) {
    const [promise, resolve, reject] = makeFuture();
    this.q.push({ asyncFunction, resolve, reject });
    this.runQueue();
    return promise;
  }
}

const dbLock = new Lock();

let taskResultPromise = dbLock.runTask(async () => {
  console.log('about to deadlock');
  let value = await dbLock.runTask(async () => { return 'value'; });
  value //?
  console.log('did not deadlock');
  return value;
});

From Wikipedia the Coffman conditions for deadlock are:

  1. Mutual exclusion - The Lock class ensures exclusive concurrent access to a database resource. The resources are (database lock, 'value' value)
  2. Hold and wait - task 1 holds the db lock and waits for 'value' from task 2. task 2 holds the 'value' and waits for the db lock
  3. No preemption - the javascript JVM has no mechanism to force either task to release their lock preemptively.
  4. Circular wait - see (2).

Upvotes: 12

Denys Séguret
Denys Séguret

Reputation: 382274

That's not a deadlock, just an infinite loop, you can't have a deadlock in JavaScript as you can't have more than one thread accessing your data.

What happens here is that as your loop never ends and the js engine being mono-thread (regarding your script), the scheduler never calls the callback you give to setTimeout. In fact you would have had exactly the same behavior without the second line.

Upvotes: 12

Related Questions