Add missing scheduled_events.md file
diff --git a/source/docs/2.4.0/celix/documents/scheduled_events.md b/source/docs/2.4.0/celix/documents/scheduled_events.md
new file mode 100644
index 0000000..988c734
--- /dev/null
+++ b/source/docs/2.4.0/celix/documents/scheduled_events.md
@@ -0,0 +1,136 @@
+---
+title: Apache Celix Events
+---
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+# Apache Celix Scheduled Events
+
+Apache Celix provides supports to schedule events on the Apache Celix Event Thread. This allows users to
+reuse the existing Apache Celix events thread to do tasks on the event thread.
+
+Scheduled events will be called repeatedly using a provided interval or once if
+only an initial delay is provided. For the interval time, a monotonic clock is used.
+
+The event callback should be relatively fast, and the scheduled event interval should be relatively high; otherwise,
+the framework event queue will be blocked, and the framework will not function properly.
+Network IO should not be done in the event callback, but instead, a separate thread should be used for this.
+
+## Scheduling an Event
+
+To schedule an event in the Apache Celix framework, use the `celix_bundleContext_scheduleEvent` C function or
+`celix::BundleContext::scheduleEvent` C++ method. For C, an options struct is used to configure the scheduled event,
+and for C++, a builder pattern is used to configure the scheduled event.
+
+### C Example
+
+```c
+#include <stdio.h>
+#include <celix_bundle_activator.h>
+
+typedef struct schedule_events_bundle_activator_data {
+ celix_bundle_context_t* ctx;
+ long scheduledEventId;
+} schedule_events_bundle_activator_data_t;
+
+void scheduleEventsBundle_oneShot(void* data) {
+ schedule_events_bundle_activator_data_t* act = data;
+ celix_bundleContext_log(act->ctx, CELIX_LOG_LEVEL_INFO, "One shot scheduled event fired");
+}
+
+void scheduleEventsBundle_process(void* data) {
+ schedule_events_bundle_activator_data_t* act = data;
+ celix_bundleContext_log(act->ctx, CELIX_LOG_LEVEL_INFO, "Recurring scheduled event fired");
+}
+
+static celix_status_t scheduleEventsBundle_start(schedule_events_bundle_activator_data_t *data, celix_bundle_context_t *ctx) {
+ data->ctx = ctx;
+
+ //schedule recurring event
+ {
+ celix_scheduled_event_options_t opts = CELIX_EMPTY_SCHEDULED_EVENT_OPTIONS;
+ opts.name = "recurring scheduled event example";
+ opts.initialDelayInSeconds = 0.1;
+ opts.intervalInSeconds = 1.0;
+ opts.callbackData = data;
+ opts.callback = scheduleEventsBundle_process;
+ data->scheduledEventId = celix_bundleContext_scheduleEvent(ctx, &opts);
+ }
+
+ //schedule one time event
+ {
+ celix_scheduled_event_options_t opts = CELIX_EMPTY_SCHEDULED_EVENT_OPTIONS;
+ opts.name = "one shot scheduled event example";
+ opts.initialDelayInSeconds = 0.1;
+ opts.callbackData = data;
+ opts.callback = scheduleEventsBundle_oneShot;
+ celix_bundleContext_scheduleEvent(ctx, &opts);
+ }
+
+ return CELIX_SUCCESS;
+}
+
+static celix_status_t scheduleEventsBundle_stop(schedule_events_bundle_activator_data_t *data, celix_bundle_context_t *ctx) {
+ celix_bundleContext_removeScheduledEvent(ctx, data->scheduledEventId);
+ return CELIX_SUCCESS;
+}
+
+CELIX_GEN_BUNDLE_ACTIVATOR(schedule_events_bundle_activator_data_t, scheduleEventsBundle_start, scheduleEventsBundle_stop)
+```
+
+### C++ Example
+
+```cpp
+#include <iostream>
+#include "celix/BundleActivator.h"
+
+class ScheduleEventsBundleActivator {
+public:
+ explicit ScheduleEventsBundleActivator(const std::shared_ptr<celix::BundleContext>& ctx) {
+ //schedule recurring event
+ event = ctx->scheduledEvent()
+ .withInitialDelay(std::chrono::milliseconds{10})
+ .withInterval(std::chrono::seconds{1})
+ .withCallback([ctx] {
+ ctx->logInfo("Recurring scheduled event fired");
+ })
+ .build();
+
+ //schedule one time event
+ ctx->scheduledEvent()
+ .withInitialDelay(std::chrono::milliseconds{10})
+ .withCallback([ctx] {
+ ctx->logInfo("One shot scheduled event fired");
+ })
+ .build();
+ }
+
+ ~ScheduleEventsBundleActivator() noexcept {
+ std::cout << "Goodbye world" << std::endl;
+ }
+private:
+ celix::ScheduledEvent event{};
+};
+
+CELIX_GEN_CXX_BUNDLE_ACTIVATOR(ScheduleEventsBundleActivator)
+```
+
+## Waking up a Scheduled Event
+
+To process a scheduled event directly, you can use the `celix_bundleContext_wakeupScheduledEvent` C function or
+`celix::ScheduledEvent::wakup` C++ method. This will wake up the scheduled event and call its callback function.