Skip to content

Commit 7c9aa70

Browse files
committed
修复协程锁协程锁爆栈卡死bug
1 parent 05a50a3 commit 7c9aa70

4 files changed

Lines changed: 61 additions & 12 deletions

File tree

Assets/BundleMaster/BundleMasterRuntime/AssetComponentLife.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public static void Update()
5555
}
5656
}
5757
DownLoadAction?.Invoke(nowTime);
58-
58+
CoroutineLockComponent.UpDate();
5959
}
6060
}
6161
}

Assets/BundleMaster/CoroutineLock/CoroutineLock.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ namespace BM
66
public class CoroutineLock : IDisposable
77
{
88
private bool _isDispose = false;
9-
internal long Key;
9+
private long _key;
1010
private CoroutineLockQueue _coroutineLockQueue;
1111
private ETTask _waitTask;
1212

1313
internal void Init(long key, CoroutineLockQueue coroutineLockQueue)
1414
{
1515
_isDispose = false;
16-
this.Key = key;
16+
this._key = key;
1717
this._coroutineLockQueue = coroutineLockQueue;
1818
_waitTask = ETTask.Create(true);
1919
}
@@ -33,12 +33,12 @@ public void Dispose()
3333
{
3434
if (_isDispose)
3535
{
36-
//Debug.LogError("协程锁重复释放");
36+
//AssetLogHelper.LogError("协程锁重复释放");
3737
return;
3838
}
3939
_waitTask = null;
4040
_isDispose = true;
41-
_coroutineLockQueue.CoroutineLockDispose(this);
41+
_coroutineLockQueue.CoroutineLockDispose(_key).Coroutine();
4242
_coroutineLockQueue = null;
4343
CoroutineLockComponent.CoroutineLockQueue.Enqueue(this);
4444

Assets/BundleMaster/CoroutineLock/CoroutineLockComponent.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Collections.Generic;
2-
using ET;
32

43
namespace BM
54
{
@@ -19,7 +18,7 @@ public static class CoroutineLockComponent
1918
/// 缓存池的池
2019
/// </summary>
2120
internal static readonly Queue<Queue<CoroutineLock>> CoroutineLockQueuePool = new Queue<Queue<CoroutineLock>>();
22-
21+
2322
public static async ETTask<CoroutineLock> Wait(CoroutineLockType coroutineLockType, long key)
2423
{
2524
if (!CoroutineLockTypeToQueue.TryGetValue(coroutineLockType, out CoroutineLockQueue coroutineLockQueue))
@@ -32,6 +31,28 @@ public static async ETTask<CoroutineLock> Wait(CoroutineLockType coroutineLockTy
3231
await coroutineLock.Wait();
3332
return coroutineLock;
3433
}
34+
35+
public static void UpDate()
36+
{
37+
for (int i = 0; i < TaskDic.Count; i++)
38+
{
39+
TaskDic[i].SetResult();
40+
}
41+
TaskDic.Clear();
42+
}
43+
44+
private static readonly List<ETTask> TaskDic = new List<ETTask>();
45+
46+
/// <summary>
47+
/// 等待一个帧循环执行
48+
/// </summary>
49+
internal static ETTask WaitTask()
50+
{
51+
ETTask tcs = ETTask.Create(true);
52+
TaskDic.Add(tcs);
53+
return tcs;
54+
}
55+
3556
}
3657
}
3758

Assets/BundleMaster/CoroutineLock/CoroutineLockQueue.cs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,57 @@
22

33
namespace BM
44
{
5+
/// <summary>
6+
/// 每个协程锁类型与其对应的队列
7+
/// </summary>
58
internal class CoroutineLockQueue
69
{
710
private CoroutineLockType _coroutineLockType;
11+
/// <summary>
12+
/// 每个key的以及其对应的队列
13+
/// </summary>
814
private readonly Dictionary<long, Queue<CoroutineLock>> _coroutineLockKeyToQueue = new Dictionary<long, Queue<CoroutineLock>>();
15+
16+
/// <summary>
17+
/// 可以瞬间完成的锁循环的数量(与设备栈大小有关)
18+
/// </summary>
19+
private const int LoopCount = 200;
20+
21+
/// <summary>
22+
/// 递归循环次数
23+
/// </summary>
24+
private readonly Dictionary<long, int> _coroutineLockKeyToLoopCount = new Dictionary<long, int>();
925

1026
internal CoroutineLockQueue(CoroutineLockType coroutineLockType)
1127
{
1228
this._coroutineLockType = coroutineLockType;
1329
}
1430

15-
internal void CoroutineLockDispose(CoroutineLock coroutineLock)
31+
internal async ETTask CoroutineLockDispose(long key)
1632
{
17-
Queue<CoroutineLock> keyToQueue = _coroutineLockKeyToQueue[coroutineLock.Key];
33+
Queue<CoroutineLock> keyToQueue = _coroutineLockKeyToQueue[key];
1834
if (keyToQueue.Count > 0)
1935
{
20-
CoroutineLock nextCoroutineLock = keyToQueue.Dequeue();
21-
nextCoroutineLock.Enable();
36+
if (_coroutineLockKeyToLoopCount[key] > 0)
37+
{
38+
_coroutineLockKeyToLoopCount[key]--;
39+
keyToQueue.Dequeue().Enable();
40+
return;
41+
}
42+
_coroutineLockKeyToLoopCount[key] = LoopCount;
43+
await CoroutineLockComponent.WaitTask();
44+
keyToQueue.Dequeue().Enable();
2245
return;
2346
}
2447
keyToQueue.Clear();
2548
CoroutineLockComponent.CoroutineLockQueuePool.Enqueue(keyToQueue);
26-
_coroutineLockKeyToQueue.Remove(coroutineLock.Key);
49+
_coroutineLockKeyToQueue.Remove(key);
50+
_coroutineLockKeyToLoopCount.Remove(key);
2751
}
2852

53+
/// <summary>
54+
/// 获取一个锁头
55+
/// </summary>
2956
internal CoroutineLock GetCoroutineLock(long key)
3057
{
3158
CoroutineLock coroutineLock;
@@ -49,6 +76,7 @@ internal CoroutineLock GetCoroutineLock(long key)
4976
{
5077
coroutineLockQueue = new Queue<CoroutineLock>();
5178
}
79+
_coroutineLockKeyToLoopCount.Add(key, LoopCount);
5280
_coroutineLockKeyToQueue.Add(key, coroutineLockQueue);
5381
coroutineLock.Enable();
5482
}

0 commit comments

Comments
 (0)