For some reason, download manager is not working properly in a worker. Considering both the main thread and worker thread are running on their own thread, I can't find the reason why download manager experiences degraded performance while using gpac in a worker.

What happens is that when using worker and a remote source, gpac takes almost 60-70 times more to load the source. It seems that the reason lies with scheduling `fetch` promises while the same thread runs gpac. I've tried a very rough way to run `fetch` in seperate threads but I think I'm still blocked by scheduling. The correct way to achieve this seems to be through native (pthread) threading for download manager. Just how `-dm-threads` option supposed to work.

I would be happy to open a PR to bring `-dm-threads` to WebAssembly version but I need some guidance on what is needed and what might be a blocking issue. @jeanlf any idea on how to proceed with this one?

**My attempt at multi-threaded fetch:**
```js
let workerScript = `self.onmessage = async function(event)
{
	let {url, options} = event.data;
	let res = await fetch(url, options);
	if (res.ok)
	{
		self.postMessage({
			ok: res.ok,
			url: res.url,
			status: res.status,
			headers: JSON.stringify([...res.headers]),
			redirected: res.redirected,
			body: res.body
		}, [res.body])
	} else self.postMessage({ok: res.ok, status: res.status})
}`;
let workerBlob = new Blob([workerScript], { type: 'application/javascript' });
fetcher._worker = new Worker(URL.createObjectURL(workerBlob));

fetcher._worker.onmessage = (event) =>
{
	if (event.data.ok)
	{
		fetcher._state = 1;
		fetcher._bytes = 0;
		fetcher._reader = event.data.body.getReader();

		let final_url = null;
		if (event.data.redirected) final_url = event.data.url;
		libgpac._fetcher_set_reply(fetcher.sess, event.data.status, final_url);

		let headers = JSON.parse(event.data.headers);
		headers.forEach(([value, key]) => {
			libgpac._fetcher_set_header(fetcher.sess, key, value);
		});
		libgpac._fetcher_set_header(fetcher.sess, 0, 0);
	}
	else
	{
		libgpac._fetcher_set_reply(fetcher.sess, event.data.status, null);
		do_log_err('fetcher for ' + url + ' failed ' + event.data.status);
		fetcher._state = 3;
	}
};

fetcher._state = 0;
fetcher._worker.postMessage({url, options}, [...(options.body ? [options.body] : [])]);
return ret;
```

**Was placed here:**
https://github.com/gpac/gpac/blob/96b474ec59b3490eed7a874b14f78ad4b3a9d2bd/src/utils/downloader.c#L7702
WebAssembly: Add threading for download manager
This is a GitHub Issue
repo:gpac
owner:gpac
Title : WebAssembly: Add threading for download manager
Issue date:

--- start body ---
For some reason, download manager is not working properly in a worker. Considering both the main thread and worker thread are running on their own thread, I can't find the reason why download manager experiences degraded performance while using gpac in a worker.

What happens is that when using worker and a remote source, gpac takes almost 60-70 times more to load the source. It seems that the reason lies with scheduling `fetch` promises while the same thread runs gpac. I've tried a very rough way to run `fetch` in seperate threads but I think I'm still blocked by scheduling. The correct way to achieve this seems to be through native (pthread) threading for download manager. Just how `-dm-threads` option supposed to work.

I would be happy to open a PR to bring `-dm-threads` to WebAssembly version but I need some guidance on what is needed and what might be a blocking issue. @jeanlf any idea on how to proceed with this one?

**My attempt at multi-threaded fetch:**
```js
let workerScript = `self.onmessage = async function(event)
{
	let {url, options} = event.data;
	let res = await fetch(url, options);
	if (res.ok)
	{
		self.postMessage({
			ok: res.ok,
			url: res.url,
			status: res.status,
			headers: JSON.stringify([...res.headers]),
			redirected: res.redirected,
			body: res.body
		}, [res.body])
	} else self.postMessage({ok: res.ok, status: res.status})
}`;
let workerBlob = new Blob([workerScript], { type: 'application/javascript' });
fetcher._worker = new Worker(URL.createObjectURL(workerBlob));

fetcher._worker.onmessage = (event) =>
{
	if (event.data.ok)
	{
		fetcher._state = 1;
		fetcher._bytes = 0;
		fetcher._reader = event.data.body.getReader();

		let final_url = null;
		if (event.data.redirected) final_url = event.data.url;
		libgpac._fetcher_set_reply(fetcher.sess, event.data.status, final_url);

		let headers = JSON.parse(event.data.headers);
		headers.forEach(([value, key]) => {
			libgpac._fetcher_set_header(fetcher.sess, key, value);
		});
		libgpac._fetcher_set_header(fetcher.sess, 0, 0);
	}
	else
	{
		libgpac._fetcher_set_reply(fetcher.sess, event.data.status, null);
		do_log_err('fetcher for ' + url + ' failed ' + event.data.status);
		fetcher._state = 3;
	}
};

fetcher._state = 0;
fetcher._worker.postMessage({url, options}, [...(options.body ? [options.body] : [])]);
return ret;
```

**Was placed here:**
https://github.com/gpac/gpac/blob/96b474ec59b3490eed7a874b14f78ad4b3a9d2bd/src/utils/downloader.c#L7702
--- end body ---

None