Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 142a61a843 | |||
| f83f2051ef |
+14
-1
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.0.2] - 2026-02-09
|
||||
|
||||
### Fixed
|
||||
- **Linux**: Fixed segfaults during rapid module reloads when file changes are detected in quick succession
|
||||
- Enabled file readiness checks on Linux (previously only used on Windows/BSD) to prevent loading partially-written shared libraries
|
||||
- Fixed inotify event deduplication to actually remove duplicate events instead of just marking them
|
||||
- Reordered reload operations to only unload old module after successfully copying new version, preventing invalid state when copy fails
|
||||
- **All platforms**: Improved reload safety by deferring module unload until after successful file copy
|
||||
|
||||
### Changed
|
||||
- Made `is_file_ready()` check available on all Unix platforms (was previously excluded on Linux)
|
||||
|
||||
## [0.0.1] - 2026-02-01
|
||||
|
||||
### Added
|
||||
@@ -25,5 +37,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Dependency management and versioning not yet implemented
|
||||
- API is unstable and subject to change in future releases
|
||||
|
||||
[Unreleased]: https://github.com/anth64/stk/compare/v0.0.1...HEAD
|
||||
[Unreleased]: https://github.com/anth64/stk/compare/v0.0.2...HEAD
|
||||
[0.0.2]: https://github.com/anth64/stk/releases/tag/v0.0.2
|
||||
[0.0.1]: https://github.com/anth64/stk/releases/tag/v0.0.1
|
||||
|
||||
@@ -173,14 +173,15 @@ stk_init();
|
||||
|
||||
## Project Status
|
||||
|
||||
**Current Version:** 0.0.1 (Pre-release)
|
||||
**Current Version:** 0.0.2 (Pre-release)
|
||||
|
||||
This is an early release proving the core hot-reload foundation. Phase 1 is still in progress.
|
||||
This is an early bugfix release improving hot-reload stability on Linux. Phase 1 is still in progress.
|
||||
|
||||
### What Works
|
||||
- Cross-platform module loading and hot-reloading
|
||||
- File watching (inotify/kqueue/FindFirstFile)
|
||||
- Basic error handling
|
||||
- Stable hot-reload even during rapid file changes (Linux fix in 0.0.2)
|
||||
|
||||
### In Progress (Phase 1)
|
||||
- Complete logging system (log levels, verbosity, output configuration)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define STK_VERSION_MAJOR 0
|
||||
#define STK_VERSION_MINOR 0
|
||||
#define STK_VERSION_PATCH 1
|
||||
#define STK_VERSION_PATCH 2
|
||||
|
||||
#define STK_STRINGIFY_HELPER(x) #x
|
||||
#define STK_STRINGIFY(x) STK_STRINGIFY_HELPER(x)
|
||||
|
||||
+19
-7
@@ -32,7 +32,6 @@ int is_mod_loaded(const char *module_name);
|
||||
uint8_t is_valid_module_file(const char *filename);
|
||||
void extract_module_id(const char *path, char *out_id);
|
||||
|
||||
#ifndef __linux__
|
||||
static uint8_t is_file_ready(const char *dir_path, const char *filename)
|
||||
{
|
||||
char full_path[STK_PATH_MAX_OS];
|
||||
@@ -80,6 +79,7 @@ static uint8_t is_file_ready(const char *dir_path, const char *filename)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
typedef struct {
|
||||
char filename[STK_PATH_MAX];
|
||||
#ifdef _WIN32
|
||||
@@ -146,7 +146,6 @@ uint8_t platform_copy_file(const char *from, const char *to)
|
||||
FILE *src = NULL, *dst = NULL;
|
||||
char tmp_path[STK_PATH_MAX_OS];
|
||||
size_t n;
|
||||
#ifndef __linux__
|
||||
char dir_path[STK_PATH_MAX_OS];
|
||||
const char *filename;
|
||||
|
||||
@@ -163,7 +162,6 @@ uint8_t platform_copy_file(const char *from, const char *to)
|
||||
|
||||
if (!is_file_ready(dir_path, filename))
|
||||
goto done;
|
||||
#endif
|
||||
|
||||
sprintf(tmp_path, "%s.tmp", to);
|
||||
|
||||
@@ -286,9 +284,8 @@ void *platform_get_symbol(void *h, const char *s)
|
||||
#endif
|
||||
}
|
||||
|
||||
char (*platform_directory_init_scan(const char *dir_path,
|
||||
size_t *out_count))[STK_PATH_MAX]
|
||||
{
|
||||
char (*platform_directory_init_scan(const char *dir_path, size_t *out_count))
|
||||
[STK_PATH_MAX] {
|
||||
size_t count = 0, i = 0, name_len;
|
||||
char (*list)[STK_PATH_MAX] = NULL;
|
||||
#ifdef _WIN32
|
||||
@@ -665,7 +662,7 @@ stk_module_event_t *platform_directory_watch_check(
|
||||
int fd = (int)(long)handle;
|
||||
char buf[STK_EVENT_BUFFER];
|
||||
ssize_t len;
|
||||
size_t index = 0, count = 0, i;
|
||||
size_t index = 0, count = 0, i, write_idx;
|
||||
stk_module_event_t *evs;
|
||||
char *ptr, *end;
|
||||
struct inotify_event *e;
|
||||
@@ -763,6 +760,21 @@ stk_module_event_t *platform_directory_watch_check(
|
||||
}
|
||||
}
|
||||
|
||||
write_idx = 0;
|
||||
for (i = 0; i < index; ++i) {
|
||||
if (evs[i] != -1) {
|
||||
if (write_idx != i) {
|
||||
evs[write_idx] = evs[i];
|
||||
strncpy((*file_list)[write_idx],
|
||||
(*file_list)[i], STK_PATH_MAX - 1);
|
||||
(*file_list)[write_idx][STK_PATH_MAX - 1] =
|
||||
'\0';
|
||||
}
|
||||
write_idx++;
|
||||
}
|
||||
}
|
||||
index = write_idx;
|
||||
|
||||
*out_count = index;
|
||||
return evs;
|
||||
|
||||
|
||||
@@ -242,9 +242,6 @@ begin_operations:
|
||||
for (i = 0; i < unload_count; ++i)
|
||||
stk_module_unload(unloaded_mod_indices[i]);
|
||||
|
||||
for (i = 0; i < reload_count; ++i)
|
||||
stk_module_unload(reloaded_mod_indices[i]);
|
||||
|
||||
for (i = 0; i < reload_count; ++i) {
|
||||
int file_index = reloaded_mod_file_indices[i];
|
||||
int mod_index = reloaded_mod_indices[i];
|
||||
@@ -261,6 +258,8 @@ begin_operations:
|
||||
continue;
|
||||
}
|
||||
|
||||
stk_module_unload(mod_index);
|
||||
|
||||
load_result = stk_module_load(tmp_path, mod_index);
|
||||
if (load_result != STK_MOD_INIT_SUCCESS) {
|
||||
stk_log(stderr, "Failed to reload module %s: %s",
|
||||
|
||||
Reference in New Issue
Block a user