Skip to content

Commit

Permalink
fix: stop device autoevents before releasing memory
Browse files Browse the repository at this point in the history
refac: eliminate recursion from dup/free list functions

Signed-off-by: Iain Anderson <iain@iotechsys.com>
  • Loading branch information
iain-anderson committed Oct 14, 2021
1 parent b33a799 commit 801750d
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 70 deletions.
1 change: 0 additions & 1 deletion scripts/Dockerfile.alpine-base
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,4 @@ RUN apk add --update --no-cache build-base wget git gcc cmake make yaml curl lib
COPY --from=builder /usr/local/include/iot /usr/local/include/iot
COPY --from=builder /usr/local/include/edgex /usr/local/include/edgex
COPY --from=builder /usr/local/lib /usr/local/lib
COPY --from=builder /usr/local/lib64 /usr/local/lib64
COPY --from=builder /usr/local/share/device-sdk-c /usr/local/share/device-sdk-c
27 changes: 9 additions & 18 deletions src/c/autoevent.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ static void *ae_runner (void *p)
{
iot_log_error
(ai->svc->logger, "Autoevent fired for unknown device %s", ai->device);
iot_schedule_remove (ai->svc->scheduler, ai->handle);
if (ai->handle)
{
iot_schedule_remove (ai->svc->scheduler, ai->handle);
}
}
edgex_autoimpl_release (ai);
return NULL;
Expand Down Expand Up @@ -193,34 +196,22 @@ void edgex_device_autoevent_start (devsdk_service_t *svc, edgex_device *dev)
}
}

static void *stopper (void *p)
static void stopper (edgex_autoimpl *ai)
{
edgex_autoimpl *ai = (edgex_autoimpl *)p;
void *handle = ai->handle;
ai->handle = NULL;
if (ai->svc->userfns.ae_stopper)
{
ai->svc->userfns.ae_stopper (ai->svc->userdata, ai->handle);
ai->svc->userfns.ae_stopper (ai->svc->userdata, handle);
}
else
{
iot_schedule_delete (ai->svc->scheduler, ai->handle);
iot_schedule_delete (ai->svc->scheduler, handle);
}
edgex_autoimpl_release (ai);
return NULL;
}

void edgex_device_autoevent_stop (edgex_device *dev)
{
for (edgex_device_autoevents *ae = dev->autos; ae; ae = ae->next)
{
if (ae->impl)
{
edgex_autoimpl *ai = ae->impl;
iot_threadpool_add_work (ai->svc->thpool, stopper, ai, -1);
}
}
}

void edgex_device_autoevent_stop_now (edgex_device *dev)
{
for (edgex_device_autoevents *ae = dev->autos; ae; ae = ae->next)
{
Expand Down
1 change: 0 additions & 1 deletion src/c/autoevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@
void edgex_device_autoevent_start (devsdk_service_t *svc, edgex_device *dev);

void edgex_device_autoevent_stop (edgex_device *dev);
void edgex_device_autoevent_stop_now (edgex_device *dev);

#endif
41 changes: 29 additions & 12 deletions src/c/devmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ static void remove_locked (edgex_devmap_t *map, edgex_device *olddev)
edgex_map_remove (&map->profiles, olddev->profile->name);
olddev->ownprofile = true;
}
edgex_device_release (map->svc, olddev);
}

/* Update a device, but fail if there could be effects on autoevents or
Expand Down Expand Up @@ -240,25 +239,33 @@ static bool update_in_place (edgex_device *dest, const edgex_device *src, edgex_

edgex_devmap_outcome_t edgex_devmap_replace_device (edgex_devmap_t *map, const edgex_device *dev)
{
edgex_device **olddev;
edgex_device **od;
edgex_device *olddev;
bool release = false;
edgex_devmap_outcome_t result = UPDATED_SDK;

pthread_rwlock_wrlock (&map->lock);
olddev = edgex_map_get (&map->devices, dev->name);
if (olddev == NULL)
od = edgex_map_get (&map->devices, dev->name);
if (od == NULL)
{
add_locked (map, dev);
result = CREATED;
}
else
{
if (!update_in_place (*olddev, dev, &result))
olddev = *od;
if (!update_in_place (olddev, dev, &result))
{
remove_locked (map, *olddev);
remove_locked (map, olddev);
add_locked (map, dev);
release = true;
}
}
pthread_rwlock_unlock (&map->lock);
if (release)
{
edgex_device_release (map->svc, olddev);
}
return result;
}

Expand Down Expand Up @@ -289,16 +296,26 @@ bool edgex_devmap_device_exists (edgex_devmap_t *map, const char *name)

bool edgex_devmap_removedevice_byname (edgex_devmap_t *map, const char *name)
{
edgex_device **olddev;
edgex_device **od;
edgex_device *olddev = NULL;

pthread_rwlock_wrlock (&map->lock);
olddev = edgex_map_get (&map->devices, name);
if (olddev)
od = edgex_map_get (&map->devices, name);
if (od)
{
remove_locked (map, *olddev);
olddev = *od;
remove_locked (map, olddev);
}
pthread_rwlock_unlock (&map->lock);
return (olddev != NULL);
if (olddev)
{
edgex_device_release (map->svc, olddev);
return true;
}
else
{
return false;
}
}

void edgex_devmap_add_profile (edgex_devmap_t *map, edgex_deviceprofile *dp)
Expand All @@ -322,7 +339,7 @@ void edgex_devmap_update_profile (devsdk_service_t *svc, edgex_deviceprofile *dp
edgex_device **dev = edgex_map_get (&svc->devices->devices, key);
if ((*dev)->profile == old)
{
edgex_device_autoevent_stop_now (*dev);
edgex_device_autoevent_stop (*dev);
(*dev)->profile = dp;
edgex_device_autoevent_start (svc, *dev);
}
Expand Down
94 changes: 56 additions & 38 deletions src/c/edgex-rest.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,16 +432,20 @@ static edgex_deviceresource *deviceresource_read
static edgex_deviceresource *edgex_deviceresource_dup (const edgex_deviceresource *e)
{
edgex_deviceresource *result = NULL;
if (e)
edgex_deviceresource **current = &result;
while (e)
{
result = malloc (sizeof (edgex_deviceresource));
result->name = strdup (e->name);
result->description = strdup (e->description);
result->tag = strdup (e->tag);
result->properties = propertyvalue_dup (e->properties);
result->attributes = iot_data_copy (e->attributes);
result->parsed_attrs = NULL;
result->next = edgex_deviceresource_dup (e->next);
edgex_deviceresource *elem = malloc (sizeof (edgex_deviceresource));
elem->name = strdup (e->name);
elem->description = strdup (e->description);
elem->tag = strdup (e->tag);
elem->properties = propertyvalue_dup (e->properties);
elem->attributes = iot_data_copy (e->attributes);
elem->parsed_attrs = NULL;
elem->next = NULL;
*current = elem;
current = &(elem->next);
e = e->next;
}
return result;
}
Expand Down Expand Up @@ -478,17 +482,20 @@ static edgex_resourceoperation *resourceoperation_read (const JSON_Object *obj)
return result;
}

static edgex_resourceoperation *resourceoperation_dup
(const edgex_resourceoperation *ro)
static edgex_resourceoperation *resourceoperation_dup (const edgex_resourceoperation *ro)
{
edgex_resourceoperation *result = NULL;
if (ro)
edgex_resourceoperation **current = &result;
while (ro)
{
result = malloc (sizeof (edgex_resourceoperation));
result->deviceResource = strdup (ro->deviceResource);
result->defaultValue = strdup (ro->defaultValue);
result->mappings = devsdk_nvpairs_dup (ro->mappings);
result->next = resourceoperation_dup (ro->next);
edgex_resourceoperation *elem = malloc (sizeof (edgex_resourceoperation));
elem->deviceResource = strdup (ro->deviceResource);
elem->defaultValue = strdup (ro->defaultValue);
elem->mappings = devsdk_nvpairs_dup (ro->mappings);
elem->next = NULL;
*current = elem;
current = &(elem->next);
ro = ro->next;
}
return result;
}
Expand Down Expand Up @@ -533,14 +540,18 @@ static edgex_devicecommand *devicecommand_read (const JSON_Object *obj)
static edgex_devicecommand *devicecommand_dup (const edgex_devicecommand *pr)
{
edgex_devicecommand *result = NULL;
if (pr)
{
result = malloc (sizeof (edgex_devicecommand));
result->name = strdup (pr->name);
result->readable = pr->readable;
result->writable = pr->writable;
result->resourceOperations = resourceoperation_dup (pr->resourceOperations);
result->next = devicecommand_dup (pr->next);
edgex_devicecommand **current = &result;
while (pr)
{
edgex_devicecommand *elem = malloc (sizeof (edgex_devicecommand));
elem->name = strdup (pr->name);
elem->readable = pr->readable;
elem->writable = pr->writable;
elem->resourceOperations = resourceoperation_dup (pr->resourceOperations);
elem->next = NULL;
*current = elem;
current = &(elem->next);
pr = pr->next;
}
return result;
}
Expand Down Expand Up @@ -656,9 +667,9 @@ edgex_deviceprofile *edgex_deviceprofile_read (iot_logger_t *lc, const char *jso

static void cmdinfo_free (edgex_cmdinfo *inf)
{
if (inf)
while (inf)
{
cmdinfo_free (inf->next);
edgex_cmdinfo *next = inf->next;
for (unsigned i = 0; i < inf->nreqs; i++)
{
free (inf->reqs[i].resource);
Expand All @@ -668,6 +679,7 @@ static void cmdinfo_free (edgex_cmdinfo *inf)
free (inf->maps);
free (inf->dfls);
free (inf);
inf = next;
}
}

Expand Down Expand Up @@ -703,26 +715,31 @@ static edgex_device_autoevents *autoevents_dup
(const edgex_device_autoevents *e)
{
edgex_device_autoevents *result = NULL;
if (e)
edgex_device_autoevents **current = &result;
while (e)
{
result = malloc (sizeof (edgex_device_autoevents));
result->resource = strdup (e->resource);
result->interval = strdup (e->interval);
result->onChange = e->onChange;
result->impl = NULL;
result->next = autoevents_dup (e->next);
edgex_device_autoevents *elem = malloc (sizeof (edgex_device_autoevents));
elem->resource = strdup (e->resource);
elem->interval = strdup (e->interval);
elem->onChange = e->onChange;
elem->impl = NULL;
elem->next = NULL;
*current = elem;
current = &(elem->next);
e = e->next;
}
return result;
}

void edgex_device_autoevents_free (edgex_device_autoevents *e)
{
if (e)
while (e)
{
edgex_device_autoevents *next = e->next;
free (e->resource);
free (e->interval);
edgex_device_autoevents_free (e->next);
free (e);
e = next;
}
}

Expand Down Expand Up @@ -770,12 +787,13 @@ devsdk_protocols *devsdk_protocols_dup (const devsdk_protocols *e)

void devsdk_protocols_free (devsdk_protocols *e)
{
if (e)
while (e)
{
devsdk_protocols *next = e->next;
free (e->name);
iot_data_free (e->properties);
devsdk_protocols_free (e->next);
free (e);
e = next;
}
}

Expand Down

0 comments on commit 801750d

Please sign in to comment.