Skip to content

Commit

Permalink
Merge branch 'master' into ci/compiler_versions
Browse files Browse the repository at this point in the history
  • Loading branch information
SingingBush authored Feb 2, 2023
2 parents 0a9f064 + f9bba26 commit 8969916
Show file tree
Hide file tree
Showing 27 changed files with 527 additions and 176 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/musl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
container: alpine

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Install dependencies
run: apk add --no-cache build-base dub ${{ matrix.dc }}
- name: Run tests
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ on:
jobs:
test:
name: Dub Tests
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
Expand All @@ -28,16 +29,13 @@ jobs:
- dmd-2.093.1
- dmd-2.092.1
- dmd-2.091.1
- dmd-2.090.1
- dmd-2.089.1
- ldc-1.28.1 # eq to dmd v2.098.1
- ldc-1.27.1 # eq to dmd v2.097.2
- ldc-1.25.1 # eq to dmd v2.095.1
- ldc-1.24.0 # eq to dmd v2.094.1
- ldc-1.23.0 # eq to dmd v2.093.1
- ldc-1.22.0 # eq to dmd v2.092.1
- ldc-1.21.0 # eq to dmd v2.091.1
- ldc-1.20.1 # eq to dmd v2.090.1
arch: [x86_64]
include:
- { os: macOS-latest, dc: dmd-latest, arch: x86_64 }
Expand All @@ -48,13 +46,12 @@ jobs:
- { os: windows-latest, dc: dmd-2.097.2, arch: x86_mscoff }
- { os: windows-latest, dc: dmd-2.096.1, arch: x86_mscoff }
- { os: windows-latest, dc: dmd-2.092.1, arch: x86_mscoff }
- { os: windows-latest, dc: dmd-2.089.1, arch: x86_mscoff }
- { os: windows-latest, dc: ldc-1.28.1, arch: x86_mscoff }
- { os: windows-latest, dc: ldc-1.20.1, arch: x86_mscoff }

runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

- name: Install D compiler
uses: dlang-community/setup-dlang@v1
Expand All @@ -66,3 +63,4 @@ jobs:
DC: ${{matrix.dc}}
ARCH: ${{matrix.arch}}
run: ./run-ci.sh
shell: bash
58 changes: 58 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,61 @@
1.22.6 - 2023-01-23
===================

- Updates compiler frontend support to range from 2.090.0 up to 2.101.2 - [pull #330][issue330]
- Fixes a socket descriptor leak after a connect timeout - [issue #331][issue331], [pull #332][issue332]
- Fixed a Windows issue when closing a TCP connection while concurrently reading from it - [pull #330][issue330]

[issue330]: https://github.com/vibe-d/vibe-core/issues/330
[issue331]: https://github.com/vibe-d/vibe-core/issues/331
[issue332]: https://github.com/vibe-d/vibe-core/issues/332


1.22.5 - 2022-11-04
===================

- Added an optional `timeout` parameter to `runEventLoopOnce` (by Grillo del Mal) - [pull #325][issue325]
- Marked `peer_address` parameters of the `UDPConnection` API as `scope` - [pull #321][issue321]
- Fixed compilation errors on iOS - [pull #323][issue323]
- Fixed an issue with non-deterministic destruction in `FixedRingBuffer` - [pull #321][issue321]
- Fixed a possible infinite recursion when using `yield()` outside of a task - [pull #326][issue326]

[issue321]: https://github.com/vibe-d/vibe-core/issues/321
[issue323]: https://github.com/vibe-d/vibe-core/issues/323
[issue325]: https://github.com/vibe-d/vibe-core/issues/325
[issue326]: https://github.com/vibe-d/vibe-core/issues/326


1.22.4 - 2022-05-26
===================

- Annotate `inout` functions with `return` (By Dennis Korpel) - [pull #313][issue313]
- Better error message for GenericPath.fromTrustedString - [pull #314][issue314]

[issue313]: https://github.com/vibe-d/vibe-core/issues/313
[issue314]: https://github.com/vibe-d/vibe-core/issues/314


1.22.3 - 2022-04-01
===================

- Added `ConnectionPool.add()/remove()` (by Ömer Faruk Irmak) - [pull #303][issue303]
- Added a timeout based overload of `TaskMutex.wait` (by Ömer Faruk Irmak) - [pull #303][issue303]
- Fixed compilation on DMD frontend/runtime version prior to 2.090.0

[issue303]: https://github.com/vibe-d/vibe-core/issues/303


1.22.2 - 2022-03-26
===================

- Fixed `parallelMap` to clean up processed elements without relying on the GC - [pull #311][issue311]
- Fixed `runWorkerTaskH`/`TaskPool.runTaskH` to not create a GC closure with the passed arguments - [pull #312][issue312]
- Fixed `isWeaklyIsolated` to consider dynamic arrays of `shared` values weakly isolated - [pull #312][issue312]

[issue311]: https://github.com/vibe-d/vibe-core/issues/311
[issue312]: https://github.com/vibe-d/vibe-core/issues/312


1.22.1 - 2022-03-04
===================

Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ Supported compilers

The following compilers are tested and supported:

- DMD 2.088.0
- DMD 2.087.1
- DMD 2.086.1
- DMD 2.101.2
- DMD 2.092.0
- DMD 2.091.1
- LDC 1.30.0
- LDC 1.20.1

Supported up to 1.22.5:
- DMD 2.085.1
- DMD 2.079.0
- LDC 1.17.0
- LDC 1.16.0
- LDC 1.15.0
- LDC 1.14.0
- LDC 1.9.0
Expand Down
2 changes: 2 additions & 0 deletions run-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
set -e -x -o pipefail

DUB_FLAGS=${DUB_FLAGS:-}
DCVER=${DC#*-}
DC=${DC%-*}
if [ "$DC" == "ldc" ]; then DC="ldc2"; fi

Expand All @@ -25,6 +26,7 @@ if [ ${BUILD_EXAMPLE=1} -eq 1 ]; then
(cd examples/$ex && dub build --compiler=$DC && dub clean)
done
fi

if [ ${RUN_TEST=1} -eq 1 ]; then
for ex in `\ls -1 tests/*.d`; do
script="${ex%.d}.sh"
Expand Down
6 changes: 2 additions & 4 deletions source/vibe/core/concurrency.d
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ unittest {
double sum = 0;

// lock() is required to access shared objects
foreach (itm; m_items.unsafeGet) {
foreach (itm; m_items) {
auto l = itm.lock();
sum += l.value;
}
Expand Down Expand Up @@ -999,7 +999,7 @@ template isWeaklyIsolated(T...)
else static if (is(T[0] == class)) enum bool isWeaklyIsolated = false;
else static if (is(T[0] == interface)) enum bool isWeaklyIsolated = false; // can't know if the implementation is isolated
else static if (is(T[0] == delegate)) enum bool isWeaklyIsolated = !!(functionAttributes!(T[0]) & (FunctionAttribute.shared_|FunctionAttribute.immutable_));
else static if (isDynamicArray!(T[0])) enum bool isWeaklyIsolated = is(typeof(T[0].init[0]) == immutable);
else static if (isDynamicArray!(T[0])) enum bool isWeaklyIsolated = is(typeof(T[0].init[0]) == immutable) || is(typeof(T[0].init[0]) == shared);
else static if (isAssociativeArray!(T[0])) enum bool isWeaklyIsolated = false; // TODO: be less strict here
else static if (isSomeFunction!(T[0])) enum bool isWeaklyIsolated = true; // functions are immutable
else static if (isPointer!(T[0])) enum bool isWeaklyIsolated = is(typeof(*T[0].init) == immutable) || is(typeof(*T[0].init) == shared);
Expand Down Expand Up @@ -1176,7 +1176,6 @@ Future!(ReturnType!CALLABLE) async(CALLABLE, ARGS...)(CALLABLE callable, ARGS ar

void test()
{
static if (__VERSION__ >= 2065) {
auto val = async({
logInfo("Starting to compute value in worker task.");
sleep(500.msecs); // simulate some lengthy computation
Expand All @@ -1188,7 +1187,6 @@ Future!(ReturnType!CALLABLE) async(CALLABLE, ARGS...)(CALLABLE callable, ARGS ar
sleep(200.msecs); // simulate some lengthy computation
logInfo("Finished computation in main task. Waiting for async value.");
logInfo("Result: %s", val.getResult());
}
}
}

Expand Down
88 changes: 85 additions & 3 deletions source/vibe/core/connectionpool.d
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ final class ConnectionPool(Connection)
m_sem.maxLocks = max_concurrent;
}
/// ditto
@property uint maxConcurrency() {
@property uint maxConcurrency() nothrow {
return m_sem.maxLocks;
}

Expand Down Expand Up @@ -125,6 +125,55 @@ final class ConnectionPool(Connection)
foreach (c; removed_conns)
disconnect_callback(c);
}

/** Removes an existing connection from the pool
It can be called with a locked connection, same connection
can be added back to the pool anytime. Any fibers that hold
a lock on this connection will keep behaving as expected.
Params:
conn = connection to remove from the pool
*/
void remove(Connection conn) @safe
{
foreach (idx, c; m_connections)
if (c is conn)
{
m_connections = m_connections[0 .. idx] ~ m_connections[idx + 1 .. $];
auto plc = conn in m_lockCount;
assert(plc !is null);
assert(*plc >= 0);
if (*plc > 0)
*plc *= -1; // invert the plc to signal LockedConnection that this connection is no longer in the pool
else
m_lockCount.remove(conn);
return;
}
assert(0, "Removing non existing conn");
}

/** Add a connection to the pool explicitly
Params:
conn = new connection to add to the pool
Returns:
success/failure
*/
bool add(Connection conn) @safe nothrow
{
if (m_connections.length < this.maxConcurrency)
{
auto plc = conn in m_lockCount;
if (plc is null)
m_lockCount[conn] = 0;
else if (*plc < 0)
*plc *= -1; // invert the plc back to positive
m_connections ~= conn;
return true;
}
return false;
}
}

///
Expand Down Expand Up @@ -227,12 +276,16 @@ struct LockedConnection(Connection) {
assert(fthis is m_task, "Locked connection destroyed in foreign task.");
auto plc = m_conn in m_pool.m_lockCount;
assert(plc !is null);
assert(*plc >= 1);
assert(*plc != 0);
//logTrace("conn %s destroy %d", cast(void*)m_conn, *plc-1);
if( --*plc == 0 ){
if( *plc > 0 && --*plc == 0 ){
() @trusted { m_pool.m_sem.unlock(); } ();
//logTrace("conn %s release", cast(void*)m_conn);
}
else if (*plc < 0 && ++*plc == 0) // connection was removed from the pool and no lock remains on it
{
m_pool.m_lockCount.remove(m_conn);
}
m_conn = Connection.init;
}
}
Expand All @@ -243,3 +296,32 @@ struct LockedConnection(Connection) {

alias __conn this;
}

///
unittest {
int id = 0;
class Connection {
public int id;
}

auto pool = new ConnectionPool!Connection({
auto conn = new Connection(); // perform the connection here
conn.id = id++;
return conn;
});

// create and lock a first connection
auto c1 = pool.lockConnection();
assert(c1.id == 0);
pool.remove(c1);
destroy(c1);

auto c2 = pool.lockConnection();
assert(c2.id == 1); // assert that we got a new connection
pool.remove(c2);
pool.add(c2);
destroy(c2);

auto c3 = pool.lockConnection();
assert(c3.id == 1); // should get the same connection back
}
44 changes: 31 additions & 13 deletions source/vibe/core/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -278,10 +278,17 @@ bool processEvents()

/**
Wait once for events and process them.
Params:
timeout = Maximum amount of time to wait for an event. A duration of
zero will cause the function to only process pending events. A
duration of `Duration.max`, if necessary, will wait indefinitely
until an event arrives.
*/
ExitReason runEventLoopOnce()
ExitReason runEventLoopOnce(Duration timeout=Duration.max)
@safe nothrow {
auto ret = s_scheduler.waitAndProcess();
auto ret = s_scheduler.waitAndProcess(timeout);
if (ret == ExitReason.idle)
performIdleProcessing();
return ret;
Expand Down Expand Up @@ -976,6 +983,13 @@ void yield()
s_scheduler.yield();
tf.handleInterrupt();
} else {
// avoid recursive event processing, which could result in an infinite
// recursion
static bool in_yield = false;
if (in_yield) return;
in_yield = true;
scope (exit) in_yield = false;

// Let yielded tasks execute
assert(TaskFiber.getThis().m_yieldLockCount == 0, "May not yield within an active yieldLock()!");
() @safe nothrow { performIdleProcessingOnce(true); } ();
Expand Down Expand Up @@ -1267,20 +1281,24 @@ Timer createTimer(void delegate() nothrow @safe callback = null)

m_running = true;

runTask((Timer tm) nothrow {
assert(m_running);
scope (exit) m_running = false;
runTask(function(Timer tm, C* ctx) nothrow {
assert(ctx.m_running);
scope (exit) ctx.m_running = false;

do {
m_pendingFire = false;
m_callback();
ctx.m_pendingFire = false;
ctx.m_callback();

// make sure that no callbacks are fired after the timer
// has been actively stopped
if (m_pendingFire && !tm.pending)
m_pendingFire = false;
} while (m_pendingFire);
}, tm);
if (ctx.m_pendingFire && !tm.pending)
ctx.m_pendingFire = false;
} while (ctx.m_pendingFire);
}, tm, () @trusted { return &this; } ());
// NOTE: the called C is allocated at a fixed address within the
// timer descriptor slot of eventcore, so that we can "safely"
// pass the address to runTask here, as long as it is
// guaranteed that the timer lives longer than the task.
}
}

Expand Down Expand Up @@ -1458,7 +1476,7 @@ void setTaskCreationCallback(TaskCreationCallback func)
/**
A version string representing the current vibe.d core version
*/
enum vibeVersionString = "1.21.0";
enum vibeVersionString = "1.22.6";


/**
Expand Down Expand Up @@ -1666,7 +1684,7 @@ private struct TimerCallbackHandler(CALLABLE) {
}

if (!eventDriver.timers.isUnique(timer) || eventDriver.timers.isPending(timer))
eventDriver.timers.wait(timer, &handle);
eventDriver.timers.wait(timer, () @trusted { return &handle; } ());
}
}

Expand Down
Loading

0 comments on commit 8969916

Please sign in to comment.