
static void js_fileio_factory_delete(JSContext *ctx, JSFileIOFactoryCtx *iofac, JSFileIOCtx *ioctx_deleted)
{
	while (gf_list_count(iofac->url_pending)) {
		JSFileIOCtx *ioctx = gf_list_pop_back(iofac->url_pending);
		gf_fileio_del(ioctx->gfio);
		gf_free(ioctx);
	}
	gf_list_del(iofac->url_pending);

	JS_SetOpaque(iofac->factory_obj, NULL);
	JS_FreeValue(ctx, iofac->factory_obj);
	JS_FreeValue(ctx, iofac->open);
	JS_FreeValue(ctx, iofac->close);
	JS_FreeValue(ctx, iofac->read);
	JS_FreeValue(ctx, iofac->write);
	JS_FreeValue(ctx, iofac->seek);
	JS_FreeValue(ctx, iofac->tell);
	JS_FreeValue(ctx, iofac->eof);
	JS_FreeValue(ctx, iofac->exists);

	//detach root (might have been closed before)
	if (!ioctx_deleted || (ioctx_deleted->factory->root != ioctx_deleted) ) {
		JS_SetOpaque(iofac->root->js_obj, NULL);
		JS_FreeValue(ctx, iofac->root->js_obj);
		gf_fileio_del(iofac->root->gfio);
		gf_free(iofac->root);
	}
	gf_free(iofac);

static void js_fileio_factory_delete(JSContext *ctx, JSFileIOFactoryCtx *iofac, JSFileIOCtx *ioctx_deleted)
{
	while (gf_list_count(iofac->url_pending)) {
		JSFileIOCtx *ioctx = gf_list_pop_back(iofac->url_pending);
		gf_fileio_del(ioctx->gfio);
		gf_free(ioctx);
	}
	gf_list_del(iofac->url_pending);

	JS_SetOpaque(iofac->factory_obj, NULL);
	JS_FreeValue(ctx, iofac->factory_obj);
	JS_FreeValue(ctx, iofac->open);
	JS_FreeValue(ctx, iofac->close);
	JS_FreeValue(ctx, iofac->read);
	JS_FreeValue(ctx, iofac->write);
	JS_FreeValue(ctx, iofac->seek);
	JS_FreeValue(ctx, iofac->tell);
	JS_FreeValue(ctx, iofac->eof);
	JS_FreeValue(ctx, iofac->exists);

	 
	if (!ioctx_deleted || (ioctx_deleted->factory->root != ioctx_deleted) ) {
		JS_SetOpaque(iofac->root->js_obj, NULL);
		JS_FreeValue(ctx, iofac->root->js_obj);
		gf_fileio_del(iofac->root->gfio);
		gf_free(iofac->root);
	}
	gf_free(iofac);