I pasted the section of triggers.inc.php dealing with birthdays into Grok and asked him to analyze it for anything in there that could trigger multiple birthday notices. This was its answer.
Quote
Yes, potential issues:

PENDING-$rightnow lock in CACHE table may fail if concurrent requests overlap, allowing multiple triggers.
No unique constraint on CACHE_VALUE for 'birthdays', risking race conditions.
trigger_birthday_notifications called multiple times if invoked externally (e.g., page load loops).

When I asked it to explain the race condition, it responded with this;

Quote
Race conditions may occur due to concurrent trigger_birthday_notifications calls, as the PENDING-$rightnow lock in the CACHE table lacks robust synchronization. Multiple requests could bypass the check, triggering duplicate emails.

To fix race conditions in UBBThreads' libs/triggers.inc.php:

Add a unique index on {$config['TABLE_PREFIX']}CACHE for CACHE_FIELD='birthdays' to prevent duplicate entries.
Use a transaction or semaphore (e.g., file lock) around the PENDING-$rightnow update and email loop.
Modify function to check and set lock atomically with SELECT ... FOR UPDATE in MySQL before proceeding.

Add unique index: Run ALTER TABLE {$config['TABLE_PREFIX']}CACHE ADD UNIQUE (CACHE_FIELD, CACHE_VALUE) WHERE CACHE_FIELD='birthdays'; via MySQL.
Implement transaction: Wrap trigger_birthday_notifications in START TRANSACTION; ... COMMIT; with SELECT ... FOR UPDATE on CACHE where CACHE_FIELD='birthdays' before updating.
Add file lock: Use flock(fopen('/tmp/ubb_birthday.lock', 'w'), LOCK_EX) before email loop, release with flock(..., LOCK_UN) after.
Test: Simulate concurrent calls to ensure single execution.

Last edited by Baldeagle; 12/22/2025 3:19 PM. Reason: Added an update

The Stovebolt Geek
https://www.stovebolt.com/ubbthreads/ubbthreads.php

Server Information
UBB.threads Version 8.0.0
Release 20240826
Server OS Linux
Server Load 0.11
Web Server Apache/2.4.37
PHP Version 8.3.11
MYSQL Version 8.0.39
Database Size 1.82 GB