mirror of
https://github.com/Ale32bit/Capy64.git
synced 2025-01-18 18:46:43 +00:00
Fix tasks crashing memory and stuff
This commit is contained in:
parent
d137c46ed9
commit
9aadc35329
5 changed files with 74 additions and 68 deletions
|
@ -24,6 +24,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
|
||||
|
@ -527,7 +528,12 @@ public class GPU : IComponent
|
|||
Height = texture.Height,
|
||||
Width = texture.Width,
|
||||
};
|
||||
task.Fulfill(buffer);
|
||||
|
||||
task.Fulfill(lk =>
|
||||
{
|
||||
ObjectManager.PushObject(lk, buffer);
|
||||
lk.SetMetaTable(GPUBufferMeta.ObjectType);
|
||||
});
|
||||
|
||||
texture.Dispose();
|
||||
});
|
||||
|
|
|
@ -25,6 +25,7 @@ using System.Net.Http;
|
|||
using System.Net.WebSockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Capy64.Runtime.Libraries;
|
||||
#nullable enable
|
||||
|
@ -198,19 +199,15 @@ public class HTTP : IComponent
|
|||
|
||||
var requestId = _requestId++;
|
||||
|
||||
var luaTask = TaskMeta.Push(L, "HTTPRequest");
|
||||
|
||||
var reqTask = _httpClient.SendAsync(request);
|
||||
reqTask.ContinueWith(async (task) =>
|
||||
{
|
||||
|
||||
if (task.IsFaulted || task.IsCanceled)
|
||||
{
|
||||
_game.LuaRuntime.QueueEvent("http_failure", LK =>
|
||||
{
|
||||
LK.PushInteger(requestId);
|
||||
LK.PushString(task.Exception?.Message);
|
||||
|
||||
return 2;
|
||||
});
|
||||
luaTask.Reject(task.Exception?.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -218,23 +215,15 @@ public class HTTP : IComponent
|
|||
|
||||
var stream = await response.Content.ReadAsStreamAsync();
|
||||
|
||||
_game.LuaRuntime.QueueEvent("http_response", LK =>
|
||||
luaTask.Fulfill(LK =>
|
||||
{
|
||||
// arg 1, request id
|
||||
LK.PushInteger(requestId);
|
||||
|
||||
// arg 2, response data
|
||||
ObjectManager.PushObject(L, stream);
|
||||
//L.PushObject(stream);
|
||||
L.SetMetaTable(FileHandle.ObjectType);
|
||||
/*if ((bool)options["binary"])
|
||||
BinaryReadHandle.Push(LK, new(stream));
|
||||
else
|
||||
ReadHandle.Push(LK, new(stream));*/
|
||||
|
||||
// arg 3, response info
|
||||
LK.NewTable();
|
||||
|
||||
LK.PushString("content");
|
||||
ObjectManager.PushObject(LK, stream);
|
||||
LK.SetMetaTable(FileHandle.ObjectType);
|
||||
LK.SetTable(-3);
|
||||
|
||||
LK.PushString("success");
|
||||
LK.PushBoolean(response.IsSuccessStatusCode);
|
||||
LK.SetTable(-3);
|
||||
|
@ -258,15 +247,9 @@ public class HTTP : IComponent
|
|||
}
|
||||
|
||||
LK.SetTable(-3);
|
||||
|
||||
return 3;
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
L.PushInteger(requestId);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Capy64.Runtime;
|
|||
public class LuaState : IDisposable
|
||||
{
|
||||
public Lua Thread;
|
||||
private readonly Lua _parent;
|
||||
public readonly Lua Parent;
|
||||
|
||||
private readonly ConcurrentQueue<LuaEvent> _queue = new();
|
||||
|
||||
|
@ -36,25 +36,21 @@ public class LuaState : IDisposable
|
|||
|
||||
public LuaState()
|
||||
{
|
||||
_parent = new Lua(false)
|
||||
Parent = new Lua(false)
|
||||
{
|
||||
Encoding = Encoding.UTF8,
|
||||
};
|
||||
|
||||
Sandbox.OpenLibraries(_parent);
|
||||
Sandbox.Patch(_parent);
|
||||
Sandbox.OpenLibraries(Parent);
|
||||
Sandbox.Patch(Parent);
|
||||
|
||||
Thread = _parent.NewThread();
|
||||
Thread = Parent.NewThread();
|
||||
|
||||
Thread.SetHook(LH_YieldTimeout, LuaHookMask.Count, 7000);
|
||||
yieldTimeoutTimer.Elapsed += (sender, ev) =>
|
||||
{
|
||||
yieldTimedOut = true;
|
||||
};
|
||||
|
||||
InitPlugins();
|
||||
|
||||
Thread.SetTop(0);
|
||||
}
|
||||
|
||||
private static void LH_YieldTimeout(IntPtr state, IntPtr ar)
|
||||
|
@ -68,6 +64,13 @@ public class LuaState : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
InitPlugins();
|
||||
|
||||
Thread.SetTop(0);
|
||||
}
|
||||
|
||||
private void InitPlugins()
|
||||
{
|
||||
var allPlugins = new List<IComponent>(Capy64.Instance.NativePlugins);
|
||||
|
@ -192,6 +195,6 @@ public class LuaState : IDisposable
|
|||
GC.SuppressFinalize(this);
|
||||
_queue.Clear();
|
||||
Thread.Close();
|
||||
_parent.Close();
|
||||
Parent.Close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,19 +44,23 @@ public class TaskMeta : IComponent
|
|||
}
|
||||
public class RuntimeTask
|
||||
{
|
||||
public RuntimeTask(string typeName)
|
||||
public RuntimeTask(string name)
|
||||
{
|
||||
TypeName = typeName;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public RuntimeTask() { }
|
||||
|
||||
public Guid Guid { get; set; } = Guid.NewGuid();
|
||||
public string TypeName { get; set; }
|
||||
public string Name { get; set; } = "object";
|
||||
public TaskStatus Status { get; set; } = TaskStatus.Running;
|
||||
public object Result { get; private set; }
|
||||
public string Error { get; private set; }
|
||||
public int DataIndex { get; private set; } = 0;
|
||||
|
||||
public void Fulfill<T>(T obj)
|
||||
{
|
||||
Status = TaskStatus.Succeeded;
|
||||
/*Status = TaskStatus.Succeeded;
|
||||
|
||||
Result = obj;
|
||||
|
||||
|
@ -65,32 +69,30 @@ public class TaskMeta : IComponent
|
|||
LK.PushString(Guid.ToString());
|
||||
|
||||
ObjectManager.PushObject(LK, obj);
|
||||
LK.SetMetaTable(TypeName);
|
||||
LK.SetMetaTable(Name);
|
||||
|
||||
LK.PushNil();
|
||||
|
||||
return 3;
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
public void Fulfill(Action<Lua> lk)
|
||||
{
|
||||
Status = TaskStatus.Succeeded;
|
||||
|
||||
var container = tasks.NewThread();
|
||||
lk(container);
|
||||
container.XMove(tasks, 1);
|
||||
tasks.Replace(-2);
|
||||
DataIndex = tasks.GetTop();
|
||||
|
||||
_game.LuaRuntime.QueueEvent("task_finish", LK =>
|
||||
{
|
||||
LK.PushString(Guid.ToString());
|
||||
|
||||
// Create Lua thread to store Lua native result data
|
||||
Result = LK.NewThread();
|
||||
var thread = (Lua)Result;
|
||||
LK.Pop(1);
|
||||
|
||||
lk(thread);
|
||||
|
||||
// Push copy of value on top and move it to LK
|
||||
thread.PushCopy(-1);
|
||||
thread.XMove(LK, 1);
|
||||
tasks.PushCopy(DataIndex);
|
||||
tasks.XMove(LK, 1);
|
||||
|
||||
LK.PushNil();
|
||||
|
||||
|
@ -176,8 +178,11 @@ public class TaskMeta : IComponent
|
|||
new(),
|
||||
};
|
||||
|
||||
private static Lua tasks;
|
||||
public void LuaInit(Lua L)
|
||||
{
|
||||
tasks = _game.LuaRuntime.Parent.NewThread();
|
||||
|
||||
CreateMeta(L);
|
||||
}
|
||||
|
||||
|
@ -211,7 +216,7 @@ public class TaskMeta : IComponent
|
|||
var obj = ObjectManager.CheckObject<RuntimeTask>(L, 1, ObjectType, gc);
|
||||
if (obj is null)
|
||||
{
|
||||
L.Error("attempt to use a closed file");
|
||||
L.Error("attempt to use a closed task");
|
||||
return null;
|
||||
}
|
||||
return obj;
|
||||
|
@ -265,7 +270,7 @@ public class TaskMeta : IComponent
|
|||
|
||||
var task = CheckTask(L, false);
|
||||
|
||||
L.PushString(task.TypeName);
|
||||
L.PushString(task.Name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -289,17 +294,9 @@ public class TaskMeta : IComponent
|
|||
|
||||
if (task.Status == TaskStatus.Succeeded)
|
||||
{
|
||||
if (task.Result is Lua thread)
|
||||
{
|
||||
// Push copy of value on top and move it to LK
|
||||
thread.PushCopy(-1);
|
||||
thread.XMove(L, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ObjectManager.PushObject(L, task.Result);
|
||||
L.SetMetaTable(task.TypeName);
|
||||
}
|
||||
// Push copy of value on top and move it to L
|
||||
tasks.PushCopy(task.DataIndex);
|
||||
tasks.XMove(L, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -329,6 +326,21 @@ public class TaskMeta : IComponent
|
|||
|
||||
private static int LM_GC(IntPtr state)
|
||||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
|
||||
var task = ToTask(L, true);
|
||||
if (task is null)
|
||||
return 0;
|
||||
|
||||
// todo: add cleanup to remove nil values at top of stack
|
||||
|
||||
if (tasks.GetTop() == task.DataIndex)
|
||||
tasks.SetTop(task.DataIndex - 1);
|
||||
else
|
||||
{
|
||||
tasks.PushNil();
|
||||
tasks.Replace(task.DataIndex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -336,7 +348,7 @@ public class TaskMeta : IComponent
|
|||
{
|
||||
var L = Lua.FromIntPtr(state);
|
||||
var task = ToTask(L);
|
||||
L.PushString("Task<{0}>: {1} ({2})", task?.TypeName, task?.Guid, task?.Status);
|
||||
L.PushString("Task<{0}>: {1} ({2})", task?.Name, task?.Guid, task?.Status);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@ internal class RuntimeManager : IComponent
|
|||
|
||||
luaState = new LuaState();
|
||||
_game.LuaRuntime = luaState;
|
||||
luaState.Init();
|
||||
|
||||
emitter = new(_game.EventEmitter, luaState);
|
||||
|
||||
|
@ -136,6 +137,7 @@ internal class RuntimeManager : IComponent
|
|||
|
||||
luaState = new LuaState();
|
||||
_game.LuaRuntime = luaState;
|
||||
luaState.Init();
|
||||
|
||||
emitter = new(_game.EventEmitter, luaState);
|
||||
|
||||
|
|
Loading…
Reference in a new issue