koffi 3.0.2 → 3.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -7
- package/cnoke.cjs +2 -2
- package/doc/benchmarks.md +2 -2
- package/doc/callbacks.md +8 -27
- package/doc/{input.md → composites.md} +161 -147
- package/doc/contribute.md +2 -1
- package/doc/index.md +0 -14
- package/doc/{functions.md → load.md} +54 -113
- package/doc/migration.md +4 -7
- package/doc/misc.md +0 -103
- package/doc/output.md +5 -11
- package/doc/pointers.md +76 -17
- package/doc/primitives.md +151 -0
- package/doc/start.md +3 -13
- package/doc/types.md +88 -0
- package/doc/unions.md +0 -186
- package/doc/values.md +134 -0
- package/index.d.ts +23 -4
- package/lib/native/base/base.cc +142 -90
- package/lib/native/base/base.hh +69 -165
- package/package.json +16 -15
- package/src/koffi/CMakeLists.txt +19 -17
- package/src/koffi/index.cjs +8 -3
- package/src/koffi/index.js +1 -1
- package/src/koffi/indirect.cjs +8 -3
- package/src/koffi/indirect.js +1 -1
- package/src/koffi/src/abi/arm64.cc +47 -62
- package/src/koffi/src/abi/riscv64.cc +38 -57
- package/src/koffi/src/abi/x64sysv.cc +38 -57
- package/src/koffi/src/abi/x64win.cc +47 -65
- package/src/koffi/src/abi/x86.cc +46 -59
- package/src/koffi/src/call.cc +239 -133
- package/src/koffi/src/call.hh +5 -10
- package/src/koffi/src/ffi.cc +211 -90
- package/src/koffi/src/ffi.hh +36 -16
- package/src/koffi/src/parser.cc +3 -3
- package/src/koffi/src/parser.hh +2 -2
- package/src/koffi/src/static.cjs +8 -0
- package/src/koffi/src/static.js +11 -0
- package/src/koffi/src/type.cc +43 -33
- package/src/koffi/src/type.hh +1 -1
- package/src/koffi/src/util.cc +73 -173
- package/src/koffi/src/util.hh +84 -43
- package/src/koffi/src/uv.cc +1 -1
- package/vendor/node-addon-api/README.md +1 -1
- package/vendor/node-addon-api/napi-inl.h +213 -35
- package/vendor/node-addon-api/napi.h +118 -7
- package/doc/variables.md +0 -102
package/lib/native/base/base.cc
CHANGED
|
@@ -186,15 +186,12 @@ void *MallocAllocator::Resize(void *ptr, Size old_size, Size new_size)
|
|
|
186
186
|
{
|
|
187
187
|
if (!new_size) {
|
|
188
188
|
Release(ptr, old_size);
|
|
189
|
-
|
|
190
|
-
} else {
|
|
191
|
-
void *new_ptr = realloc(ptr, (size_t)new_size);
|
|
192
|
-
K_CRITICAL(new_ptr || !new_size, "Failed to resize %1 memory block to %2",
|
|
193
|
-
FmtMemSize(old_size), FmtMemSize(new_size));
|
|
194
|
-
|
|
195
|
-
ptr = new_ptr;
|
|
189
|
+
return nullptr;
|
|
196
190
|
}
|
|
197
191
|
|
|
192
|
+
ptr = realloc(ptr, (size_t)new_size);
|
|
193
|
+
K_CRITICAL(ptr || !new_size, "Failed to resize %1 memory block to %2", FmtMemSize(old_size), FmtMemSize(new_size));
|
|
194
|
+
|
|
198
195
|
return ptr;
|
|
199
196
|
}
|
|
200
197
|
|
|
@@ -216,6 +213,8 @@ Allocator *GetNullAllocator()
|
|
|
216
213
|
LinkedAllocator& LinkedAllocator::operator=(LinkedAllocator &&other)
|
|
217
214
|
{
|
|
218
215
|
ReleaseAll();
|
|
216
|
+
|
|
217
|
+
allocator = other.allocator;
|
|
219
218
|
list = other.list;
|
|
220
219
|
other.list = nullptr;
|
|
221
220
|
|
|
@@ -363,10 +362,13 @@ BlockAllocator& BlockAllocator::operator=(BlockAllocator &&other)
|
|
|
363
362
|
allocator.operator=(std::move(other.allocator));
|
|
364
363
|
|
|
365
364
|
block_size = other.block_size;
|
|
366
|
-
|
|
365
|
+
|
|
366
|
+
bucket_ptr = other.bucket_ptr;
|
|
367
|
+
bucket_end = other.bucket_end;
|
|
367
368
|
last_alloc = other.last_alloc;
|
|
368
369
|
|
|
369
|
-
other.
|
|
370
|
+
other.bucket_ptr = nullptr;
|
|
371
|
+
other.bucket_end = nullptr;
|
|
370
372
|
other.last_alloc = nullptr;
|
|
371
373
|
|
|
372
374
|
return *this;
|
|
@@ -374,19 +376,23 @@ BlockAllocator& BlockAllocator::operator=(BlockAllocator &&other)
|
|
|
374
376
|
|
|
375
377
|
void BlockAllocator::Reset()
|
|
376
378
|
{
|
|
377
|
-
|
|
379
|
+
if (bucket_ptr) {
|
|
380
|
+
bucket_ptr = bucket_end - block_size;
|
|
381
|
+
|
|
382
|
+
// Not true but Resize code assumes that last_alloc is not null when a bucket exists.
|
|
383
|
+
// I could also let it as-is, but for some reason I find that less clean.
|
|
384
|
+
last_alloc = bucket_ptr;
|
|
378
385
|
|
|
379
|
-
|
|
380
|
-
current_bucket->used = 0;
|
|
381
|
-
allocator.ReleaseAllExcept(current_bucket);
|
|
386
|
+
allocator.ReleaseAllExcept(bucket_ptr);
|
|
382
387
|
} else {
|
|
383
|
-
|
|
388
|
+
ReleaseAll();
|
|
384
389
|
}
|
|
385
390
|
}
|
|
386
391
|
|
|
387
392
|
void BlockAllocator::ReleaseAll()
|
|
388
393
|
{
|
|
389
|
-
|
|
394
|
+
bucket_ptr = nullptr;
|
|
395
|
+
bucket_end = nullptr;
|
|
390
396
|
last_alloc = nullptr;
|
|
391
397
|
|
|
392
398
|
allocator.ReleaseAll();
|
|
@@ -396,88 +402,78 @@ void *BlockAllocator::Allocate(Size size)
|
|
|
396
402
|
{
|
|
397
403
|
K_ASSERT(size >= 0);
|
|
398
404
|
|
|
399
|
-
|
|
400
|
-
|
|
405
|
+
uint8_t *ptr = bucket_ptr;
|
|
406
|
+
|
|
407
|
+
// Fast path
|
|
408
|
+
if (uint8_t *new_ptr = AlignUp(ptr + size, 8); new_ptr <= bucket_end) [[likely]] {
|
|
409
|
+
bucket_ptr = new_ptr;
|
|
401
410
|
|
|
402
|
-
|
|
403
|
-
uint8_t *ptr = (uint8_t *)allocator.Allocate(size);
|
|
411
|
+
last_alloc = ptr;
|
|
404
412
|
return ptr;
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (size <= block_size) {
|
|
416
|
+
bucket_ptr = (uint8_t *)allocator.Allocate(block_size);
|
|
417
|
+
bucket_end = bucket_ptr + block_size;
|
|
410
418
|
|
|
411
|
-
|
|
412
|
-
|
|
419
|
+
ptr = bucket_ptr;
|
|
420
|
+
bucket_ptr = AlignUp(ptr + size, 8);
|
|
413
421
|
|
|
414
422
|
last_alloc = ptr;
|
|
415
423
|
return ptr;
|
|
416
424
|
}
|
|
425
|
+
|
|
426
|
+
// Fallback for big allocations
|
|
427
|
+
return allocator.Allocate(size);
|
|
417
428
|
}
|
|
418
429
|
|
|
419
430
|
void *BlockAllocator::Resize(void *ptr, Size old_size, Size new_size)
|
|
420
431
|
{
|
|
421
432
|
K_ASSERT(old_size >= 0);
|
|
422
433
|
K_ASSERT(new_size >= 0);
|
|
434
|
+
K_ASSERT(ptr || !old_size);
|
|
423
435
|
|
|
424
436
|
if (!new_size) {
|
|
425
437
|
Release(ptr, old_size);
|
|
426
|
-
|
|
427
|
-
}
|
|
428
|
-
if (!ptr) {
|
|
429
|
-
old_size = 0;
|
|
430
|
-
}
|
|
438
|
+
return nullptr;
|
|
439
|
+
}
|
|
431
440
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
441
|
+
// Fast path
|
|
442
|
+
if (uint8_t *new_ptr = AlignUp((uint8_t *)ptr + new_size, 8); ptr == last_alloc && new_ptr <= bucket_end) {
|
|
443
|
+
K_ASSERT(ptr);
|
|
435
444
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
!AllocateSeparately(aligned_new_size)) {
|
|
440
|
-
current_bucket->used += aligned_delta;
|
|
441
|
-
} else if (AllocateSeparately(aligned_old_size)) {
|
|
442
|
-
ptr = allocator.Resize(ptr, old_size, new_size);
|
|
443
|
-
} else {
|
|
444
|
-
void *new_ptr = Allocate(new_size);
|
|
445
|
+
bucket_ptr = new_ptr;
|
|
446
|
+
return ptr;
|
|
447
|
+
}
|
|
445
448
|
|
|
446
|
-
|
|
447
|
-
|
|
449
|
+
if (old_size <= block_size) {
|
|
450
|
+
uint8_t *copy_ptr = (uint8_t *)Allocate(new_size);
|
|
451
|
+
Size copy_len = std::min(old_size, new_size);
|
|
448
452
|
|
|
449
|
-
|
|
450
|
-
|
|
453
|
+
MemCpy(copy_ptr, ptr, copy_len);
|
|
454
|
+
|
|
455
|
+
return copy_ptr;
|
|
451
456
|
}
|
|
452
457
|
|
|
453
|
-
|
|
458
|
+
// Old allocation fell back to separate allocation, we can resize at will now!
|
|
459
|
+
return allocator.Resize(ptr, old_size, new_size);
|
|
454
460
|
}
|
|
455
461
|
|
|
456
462
|
void BlockAllocator::Release(const void *ptr, Size size)
|
|
457
463
|
{
|
|
458
464
|
K_ASSERT(size >= 0);
|
|
459
465
|
|
|
460
|
-
if (ptr) {
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
current_bucket->used -= aligned_size;
|
|
465
|
-
|
|
466
|
-
if (!current_bucket->used) {
|
|
467
|
-
allocator.Release(current_bucket, K_SIZE(Bucket) + block_size);
|
|
468
|
-
current_bucket = nullptr;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
last_alloc = nullptr;
|
|
472
|
-
} else if (AllocateSeparately(aligned_size)) {
|
|
473
|
-
allocator.Release(ptr, size);
|
|
474
|
-
}
|
|
466
|
+
if (ptr == last_alloc) {
|
|
467
|
+
bucket_ptr = last_alloc;
|
|
468
|
+
} else if (size > block_size) {
|
|
469
|
+
allocator.Release(ptr, size);
|
|
475
470
|
}
|
|
476
471
|
}
|
|
477
472
|
|
|
478
473
|
void BlockAllocator::GiveTo(LinkedAllocator *alloc)
|
|
479
474
|
{
|
|
480
|
-
|
|
475
|
+
bucket_ptr = nullptr;
|
|
476
|
+
bucket_end = nullptr;
|
|
481
477
|
last_alloc = nullptr;
|
|
482
478
|
|
|
483
479
|
allocator.GiveTo(alloc);
|
|
@@ -1511,7 +1507,7 @@ static inline void ProcessArg(const FmtArg &arg, AppendFunc append)
|
|
|
1511
1507
|
append(FormatUnsignedToDecimal((uint64_t)arg.u.date.st.day, buf));
|
|
1512
1508
|
} break;
|
|
1513
1509
|
|
|
1514
|
-
case FmtType::
|
|
1510
|
+
case FmtType::TimeBasic: {
|
|
1515
1511
|
const TimeSpec &spec = arg.u.time.spec;
|
|
1516
1512
|
|
|
1517
1513
|
LocalArray<char, 128> buf;
|
|
@@ -1548,6 +1544,43 @@ static inline void ProcessArg(const FmtArg &arg, AppendFunc append)
|
|
|
1548
1544
|
|
|
1549
1545
|
append(buf);
|
|
1550
1546
|
} break;
|
|
1547
|
+
case FmtType::TimeIso: {
|
|
1548
|
+
const TimeSpec &spec = arg.u.time.spec;
|
|
1549
|
+
|
|
1550
|
+
LocalArray<char, 128> buf;
|
|
1551
|
+
|
|
1552
|
+
if (spec.offset && arg.u.time.ms) {
|
|
1553
|
+
int offset_h = spec.offset / 60;
|
|
1554
|
+
int offset_m = spec.offset % 60;
|
|
1555
|
+
|
|
1556
|
+
buf.len = Fmt(buf.data, "%1-%2-%3T%4:%5:%6.%7%8%9%10",
|
|
1557
|
+
FmtInt(spec.year, 2), FmtInt(spec.month, 2),
|
|
1558
|
+
FmtInt(spec.day, 2), FmtInt(spec.hour, 2),
|
|
1559
|
+
FmtInt(spec.min, 2), FmtInt(spec.sec, 2), FmtInt(spec.msec, 3),
|
|
1560
|
+
offset_h >= 0 ? "+" : "", FmtInt(offset_h, 2), FmtInt(offset_m, 2)).len;
|
|
1561
|
+
} else if (spec.offset) {
|
|
1562
|
+
int offset_h = spec.offset / 60;
|
|
1563
|
+
int offset_m = spec.offset % 60;
|
|
1564
|
+
|
|
1565
|
+
buf.len = Fmt(buf.data, "%1-%2-%3T%4:%5:%6%7%8%9",
|
|
1566
|
+
FmtInt(spec.year, 2), FmtInt(spec.month, 2),
|
|
1567
|
+
FmtInt(spec.day, 2), FmtInt(spec.hour, 2),
|
|
1568
|
+
FmtInt(spec.min, 2), FmtInt(spec.sec, 2),
|
|
1569
|
+
offset_h >= 0 ? "+" : "", FmtInt(offset_h, 2), FmtInt(offset_m, 2)).len;
|
|
1570
|
+
} else if (arg.u.time.ms) {
|
|
1571
|
+
buf.len = Fmt(buf.data, "%1-%2-%3T%4:%5:%6.%7Z",
|
|
1572
|
+
FmtInt(spec.year, 2), FmtInt(spec.month, 2),
|
|
1573
|
+
FmtInt(spec.day, 2), FmtInt(spec.hour, 2),
|
|
1574
|
+
FmtInt(spec.min, 2), FmtInt(spec.sec, 2), FmtInt(spec.msec, 3)).len;
|
|
1575
|
+
} else {
|
|
1576
|
+
buf.len = Fmt(buf.data, "%1-%2-%3T%4:%5:%6Z",
|
|
1577
|
+
FmtInt(spec.year, 2), FmtInt(spec.month, 2),
|
|
1578
|
+
FmtInt(spec.day, 2), FmtInt(spec.hour, 2),
|
|
1579
|
+
FmtInt(spec.min, 2), FmtInt(spec.sec, 2)).len;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
append(buf);
|
|
1583
|
+
} break;
|
|
1551
1584
|
case FmtType::TimeNice: {
|
|
1552
1585
|
const TimeSpec &spec = arg.u.time.spec;
|
|
1553
1586
|
|
|
@@ -1947,7 +1980,7 @@ void FmtUrlSafe::Format(FunctionRef<void(Span<const char>)> append) const
|
|
|
1947
1980
|
}
|
|
1948
1981
|
}
|
|
1949
1982
|
|
|
1950
|
-
void
|
|
1983
|
+
void FmtXmlSafe::Format(FunctionRef<void(Span<const char>)> append) const
|
|
1951
1984
|
{
|
|
1952
1985
|
for (char c: str) {
|
|
1953
1986
|
switch (c) {
|
|
@@ -5171,7 +5204,7 @@ bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
|
5171
5204
|
|
|
5172
5205
|
// Read and write standard process streams
|
|
5173
5206
|
{
|
|
5174
|
-
bool running =
|
|
5207
|
+
bool running = in_func.IsValid() || out_func.IsValid();
|
|
5175
5208
|
|
|
5176
5209
|
PendingIO proc_in;
|
|
5177
5210
|
Span<const uint8_t> write_buf = {};
|
|
@@ -5201,6 +5234,7 @@ bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
|
5201
5234
|
}
|
|
5202
5235
|
} else {
|
|
5203
5236
|
CloseHandleSafe(&in_pipe[1]);
|
|
5237
|
+
running &= out_func.IsValid();
|
|
5204
5238
|
}
|
|
5205
5239
|
}
|
|
5206
5240
|
|
|
@@ -5632,7 +5666,7 @@ bool ExecuteCommandLine(const char *cmd_line, const ExecuteInfo &info,
|
|
|
5632
5666
|
return true;
|
|
5633
5667
|
}
|
|
5634
5668
|
|
|
5635
|
-
Size ReadCommandOutput(const char *cmd_line, Span<
|
|
5669
|
+
Size ReadCommandOutput(const char *cmd_line, Span<uint8_t> out_output)
|
|
5636
5670
|
{
|
|
5637
5671
|
static ExecuteInfo::KeyValue variables[] = {
|
|
5638
5672
|
{ "LANG", "C" },
|
|
@@ -5651,34 +5685,48 @@ Size ReadCommandOutput(const char *cmd_line, Span<char> out_output)
|
|
|
5651
5685
|
};
|
|
5652
5686
|
|
|
5653
5687
|
int exit_code;
|
|
5654
|
-
if (!ExecuteCommandLine(cmd_line, info, MakeSpan((const uint8_t *)nullptr, 0), write, &exit_code))
|
|
5688
|
+
if (!ExecuteCommandLine(cmd_line, info, MakeSpan((const uint8_t *)nullptr, 0), write, &exit_code)) {
|
|
5689
|
+
if (out_output.len) {
|
|
5690
|
+
Span<const char> output = out_output.As<const char>();
|
|
5691
|
+
LogError("Command '%1' failed: %2", cmd_line, output);
|
|
5692
|
+
}
|
|
5655
5693
|
return -1;
|
|
5694
|
+
}
|
|
5656
5695
|
if (exit_code) {
|
|
5657
|
-
LogDebug("Command '%1 failed (exit code: %2)", cmd_line, exit_code);
|
|
5696
|
+
LogDebug("Command '%1' failed (exit code: %2)", cmd_line, exit_code);
|
|
5658
5697
|
return -1;
|
|
5659
5698
|
}
|
|
5660
5699
|
|
|
5661
5700
|
return total_len;
|
|
5662
5701
|
}
|
|
5663
5702
|
|
|
5664
|
-
bool ReadCommandOutput(const char *cmd_line, HeapArray<
|
|
5703
|
+
bool ReadCommandOutput(const char *cmd_line, HeapArray<uint8_t> *out_output)
|
|
5665
5704
|
{
|
|
5666
5705
|
static ExecuteInfo::KeyValue variables[] = {
|
|
5667
5706
|
{ "LANG", "C" },
|
|
5668
5707
|
{ "LC_ALL", "C" }
|
|
5669
5708
|
};
|
|
5670
5709
|
|
|
5710
|
+
Size start_len = out_output->len;
|
|
5711
|
+
K_DEFER_N(err_guard) { out_output->RemoveFrom(start_len); };
|
|
5712
|
+
|
|
5671
5713
|
ExecuteInfo info = {};
|
|
5672
5714
|
info.env_variables = variables;
|
|
5673
5715
|
|
|
5674
5716
|
int exit_code;
|
|
5675
|
-
if (!ExecuteCommandLine(cmd_line, info, {}, Mebibytes(1), out_output, &exit_code))
|
|
5717
|
+
if (!ExecuteCommandLine(cmd_line, info, {}, Mebibytes(1), out_output, &exit_code)) {
|
|
5718
|
+
if (out_output->len > start_len) {
|
|
5719
|
+
Span<const char> output = out_output->Take(start_len, out_output->len - start_len).As<const char>();
|
|
5720
|
+
LogError("Command '%1' failed: %2", cmd_line, output);
|
|
5721
|
+
}
|
|
5676
5722
|
return false;
|
|
5723
|
+
}
|
|
5677
5724
|
if (exit_code) {
|
|
5678
|
-
LogDebug("Command '%1 failed (exit code: %2)", cmd_line, exit_code);
|
|
5725
|
+
LogDebug("Command '%1' failed (exit code: %2)", cmd_line, exit_code);
|
|
5679
5726
|
return false;
|
|
5680
5727
|
}
|
|
5681
5728
|
|
|
5729
|
+
err_guard.Disable();
|
|
5682
5730
|
return true;
|
|
5683
5731
|
}
|
|
5684
5732
|
|
|
@@ -7405,7 +7453,7 @@ public:
|
|
|
7405
7453
|
void AddTask(Async *async, int worker_idx, const std::function<bool()> &func);
|
|
7406
7454
|
|
|
7407
7455
|
void RunWorker(int worker_idx);
|
|
7408
|
-
void SyncOn(Async *async,
|
|
7456
|
+
void SyncOn(Async *async, Async *only);
|
|
7409
7457
|
bool WaitOn(Async *async, int timeout);
|
|
7410
7458
|
|
|
7411
7459
|
void RunTasks(int worker_idx, Async *only);
|
|
@@ -7419,7 +7467,7 @@ static thread_local AsyncPool *async_running_pool = nullptr;
|
|
|
7419
7467
|
static thread_local int async_running_worker_idx;
|
|
7420
7468
|
static thread_local bool async_running_task = false;
|
|
7421
7469
|
|
|
7422
|
-
Async::Async(int threads)
|
|
7470
|
+
Async::Async(int threads, unsigned int flags)
|
|
7423
7471
|
{
|
|
7424
7472
|
K_ASSERT(threads);
|
|
7425
7473
|
|
|
@@ -7441,14 +7489,22 @@ Async::Async(int threads)
|
|
|
7441
7489
|
}
|
|
7442
7490
|
|
|
7443
7491
|
pool->RegisterAsync();
|
|
7492
|
+
|
|
7493
|
+
if (flags & (int)AsyncFlag::Selfish) {
|
|
7494
|
+
only = this;
|
|
7495
|
+
}
|
|
7444
7496
|
}
|
|
7445
7497
|
|
|
7446
|
-
Async::Async(Async *parent)
|
|
7498
|
+
Async::Async(Async *parent, unsigned int flags)
|
|
7447
7499
|
{
|
|
7448
7500
|
K_ASSERT(parent);
|
|
7449
7501
|
|
|
7450
7502
|
pool = parent->pool;
|
|
7451
7503
|
pool->RegisterAsync();
|
|
7504
|
+
|
|
7505
|
+
if (flags & (int)AsyncFlag::Selfish) {
|
|
7506
|
+
only = this;
|
|
7507
|
+
}
|
|
7452
7508
|
}
|
|
7453
7509
|
|
|
7454
7510
|
Async::~Async()
|
|
@@ -7471,13 +7527,7 @@ void Async::Run(int worker, const std::function<bool()> &func)
|
|
|
7471
7527
|
|
|
7472
7528
|
bool Async::Sync()
|
|
7473
7529
|
{
|
|
7474
|
-
pool->SyncOn(this,
|
|
7475
|
-
return success;
|
|
7476
|
-
}
|
|
7477
|
-
|
|
7478
|
-
bool Async::SyncSoon()
|
|
7479
|
-
{
|
|
7480
|
-
pool->SyncOn(this, true);
|
|
7530
|
+
pool->SyncOn(this, only);
|
|
7481
7531
|
return success;
|
|
7482
7532
|
}
|
|
7483
7533
|
|
|
@@ -7613,7 +7663,7 @@ void AsyncPool::AddTask(Async *async, int worker_idx, const std::function<bool()
|
|
|
7613
7663
|
int worker_idx = async_running_worker_idx;
|
|
7614
7664
|
|
|
7615
7665
|
do {
|
|
7616
|
-
RunTasks(worker_idx,
|
|
7666
|
+
RunTasks(worker_idx, async->only);
|
|
7617
7667
|
} while (pending_tasks >= K_ASYNC_MAX_PENDING_TASKS);
|
|
7618
7668
|
} else if (!prev_pending) {
|
|
7619
7669
|
std::lock_guard<std::mutex> lock_pool(pool_mutex);
|
|
@@ -7647,7 +7697,7 @@ void AsyncPool::RunWorker(int worker_idx)
|
|
|
7647
7697
|
}
|
|
7648
7698
|
}
|
|
7649
7699
|
|
|
7650
|
-
void AsyncPool::SyncOn(Async *async,
|
|
7700
|
+
void AsyncPool::SyncOn(Async *async, Async *only)
|
|
7651
7701
|
{
|
|
7652
7702
|
K_DEFER_C(pool = async_running_pool,
|
|
7653
7703
|
worker_idx = async_running_worker_idx) {
|
|
@@ -7659,7 +7709,7 @@ void AsyncPool::SyncOn(Async *async, bool soon)
|
|
|
7659
7709
|
async_running_worker_idx = 0;
|
|
7660
7710
|
|
|
7661
7711
|
while (async->remaining_tasks) {
|
|
7662
|
-
RunTasks(0,
|
|
7712
|
+
RunTasks(0, only);
|
|
7663
7713
|
|
|
7664
7714
|
std::unique_lock<std::mutex> lock_sync(pool_mutex);
|
|
7665
7715
|
sync_cv.wait(lock_sync, [&]() { return pending_tasks || !async->remaining_tasks; });
|
|
@@ -7739,12 +7789,12 @@ void AsyncPool::RunTask(Task *task)
|
|
|
7739
7789
|
#else
|
|
7740
7790
|
|
|
7741
7791
|
|
|
7742
|
-
Async::Async(int threads)
|
|
7792
|
+
Async::Async(int threads, unsigned int)
|
|
7743
7793
|
{
|
|
7744
7794
|
K_ASSERT(threads);
|
|
7745
7795
|
}
|
|
7746
7796
|
|
|
7747
|
-
Async::Async(Async *parent)
|
|
7797
|
+
Async::Async(Async *parent, unsigned int)
|
|
7748
7798
|
{
|
|
7749
7799
|
K_ASSERT(parent);
|
|
7750
7800
|
}
|
|
@@ -10728,7 +10778,7 @@ const char *GetMimeType(Span<const char> extension, const char *default_type)
|
|
|
10728
10778
|
const char *mimetype = mimetypes.FindValue(lower, nullptr);
|
|
10729
10779
|
|
|
10730
10780
|
if (!mimetype) {
|
|
10731
|
-
|
|
10781
|
+
LogDebug("Unknown MIME type for extension '%1'", extension);
|
|
10732
10782
|
mimetype = default_type;
|
|
10733
10783
|
}
|
|
10734
10784
|
|
|
@@ -10768,8 +10818,10 @@ bool CanCompressFile(const char *filename)
|
|
|
10768
10818
|
if (TestStrI(extension, ".db") || TestStrI(extension, ".sqlite3"))
|
|
10769
10819
|
return false;
|
|
10770
10820
|
|
|
10771
|
-
const char *mimetype = GetMimeType(extension);
|
|
10821
|
+
const char *mimetype = GetMimeType(extension, nullptr);
|
|
10772
10822
|
|
|
10823
|
+
if (!mimetype)
|
|
10824
|
+
return false;
|
|
10773
10825
|
if (StartsWith(mimetype, "video/"))
|
|
10774
10826
|
return false;
|
|
10775
10827
|
if (StartsWith(mimetype, "audio/"))
|