@@ -55,7 +55,24 @@ bool LIVEUPDATE_PERFORM_SANITY_CHECKS = true;
5555
5656using namespace liu ;
5757
58- static size_t update_store_data (void * location, LiveUpdate::storage_func, const buffer_t *);
58+ static size_t update_store_data (void * location, const buffer_t *);
59+
60+ // serialization callbacks
61+ static std::unordered_map<std::string, LiveUpdate::storage_func> storage_callbacks;
62+
63+ void LiveUpdate::register_serialization_callback (std::string key, storage_func callback)
64+ {
65+ auto it = storage_callbacks.find (key);
66+ if (it == storage_callbacks.end ())
67+ {
68+ storage_callbacks.emplace (std::piecewise_construct,
69+ std::forward_as_tuple (std::move (key)),
70+ std::forward_as_tuple (std::move (callback)));
71+ }
72+ else {
73+ throw std::runtime_error (" Storage key '" + key + " ' already used" );
74+ }
75+ }
5976
6077template <typename Class>
6178inline bool validate_header (const Class* hdr)
@@ -66,8 +83,7 @@ inline bool validate_header(const Class* hdr)
6683 hdr->e_ident [3 ] == ' F' ;
6784}
6885
69- void LiveUpdate::begin (buffer_t blob,
70- storage_func storage_callback)
86+ void LiveUpdate::begin (buffer_t blob)
7187{
7288 void * location = OS::liveupdate_storage_area ();
7389 LPRINT (" LiveUpdate::begin(%p, %p:%d, ...)\n " , location, blob.data (), (int ) blob.size ());
@@ -172,7 +188,7 @@ void LiveUpdate::begin(buffer_t blob,
172188 LPRINT (" * _start is located at %#x\n " , start_offset);
173189
174190 // save ourselves if function passed
175- update_store_data (storage_area, storage_callback, &blob);
191+ update_store_data (storage_area, &blob);
176192
177193 // 2. flush all devices with flush() interface
178194 hw::Devices::flush_all ();
@@ -225,10 +241,10 @@ void LiveUpdate::restore_environment()
225241 // enable interrupts again
226242 asm volatile (" sti" );
227243}
228- buffer_t LiveUpdate::store (storage_func func )
244+ buffer_t LiveUpdate::store ()
229245{
230246 char * location = (char *) OS::liveupdate_storage_area ();
231- size_t size = update_store_data (location, func, nullptr );
247+ size_t size = update_store_data (location, nullptr );
232248 return buffer_t (location, location + size);
233249}
234250
@@ -251,17 +267,17 @@ size_t LiveUpdate::stored_data_length(void* location)
251267 return storage->total_bytes ();
252268}
253269
254- size_t update_store_data (void * location, LiveUpdate::storage_func func, const buffer_t * blob)
270+ size_t update_store_data (void * location, const buffer_t * blob)
255271{
256272 // create storage header in the fixed location
257273 new (location) storage_header ();
258274 auto * storage = (storage_header*) location;
259275
260276 // / callback for storing stuff, if provided
261- if (func != nullptr )
277+ for ( const auto & pair : storage_callbacks )
262278 {
263279 Storage wrapper {*storage};
264- func (wrapper, blob);
280+ pair. second (wrapper, blob);
265281 }
266282
267283 // / finalize
0 commit comments