void chip_deleter(::gpiod_chip* chip)
{
- ::gpiod_chip_close(chip);
+ ::gpiod_chip_unref(chip);
}
} /* namespace */
static void gpiod_Chip_dealloc(gpiod_ChipObject *self)
{
if (self->chip)
- gpiod_chip_close(self->chip);
+ gpiod_chip_unref(self->chip);
PyObject_Del(self);
}
if (gpiod_ChipIsClosed(self))
return NULL;
- gpiod_chip_close(self->chip);
+ gpiod_chip_unref(self->chip);
self->chip = NULL;
Py_RETURN_NONE;
struct gpiod_chip *gpiod_chip_open(const char *path) GPIOD_API;
/**
- * @brief Close a GPIO chip handle and release all allocated resources.
+ * @brief Increase the refcount on this GPIO object.
* @param chip The GPIO chip object.
+ * @return Passed reference to the GPIO chip.
*/
-void gpiod_chip_close(struct gpiod_chip *chip) GPIOD_API;
+struct gpiod_chip *gpiod_chip_ref(struct gpiod_chip *chip) GPIOD_API;
+
+/**
+ * @brief Decrease the refcount on this GPIO object. If the refcount reaches 0,
+ * close the chip device and free all associated resources.
+ * @param chip The GPIO chip object.
+ */
+void gpiod_chip_unref(struct gpiod_chip *chip) GPIOD_API;
/**
* @brief Get the GPIO chip name as represented in the kernel.
};
struct gpiod_chip {
+ int refcount;
+
struct gpiod_line **lines;
unsigned int num_lines;
chip->fd = fd;
chip->num_lines = info.lines;
+ chip->refcount = 1;
/*
* GPIO device must have a name - don't bother checking this field. In
return NULL;
}
-void gpiod_chip_close(struct gpiod_chip *chip)
+struct gpiod_chip *gpiod_chip_ref(struct gpiod_chip *chip)
+{
+ chip->refcount++;
+ return chip;
+}
+
+void gpiod_chip_unref(struct gpiod_chip *chip)
{
struct gpiod_line *line;
unsigned int i;
+ chip->refcount--;
+ if (chip->refcount > 0)
+ return;
+
if (chip->lines) {
for (i = 0; i < chip->num_lines; i++) {
line = chip->lines[i];
typedef struct gpiod_chip gpiod_chip_struct;
typedef struct gpiod_line_bulk gpiod_line_bulk_struct;
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_chip_struct, gpiod_chip_close);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_chip_struct, gpiod_chip_unref);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(gpiod_line_bulk_struct, gpiod_line_bulk_free);
/* These are private definitions and should not be used directly. */
gpiod_chip_label(chip),
gpiod_chip_num_lines(chip));
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
free(entries[i]);
}
if (offset >= 0) {
printf("%s %u\n",
gpiod_chip_name(chip), offset);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
return EXIT_SUCCESS;
}
}
printf("\n");
gpiod_line_release_bulk(lines);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
gpiod_line_bulk_free(lines);
free(values);
free(offsets);
list_lines(chip);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
}
} else {
for (i = 0; i < argc; i++) {
list_lines(chip);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
}
}
gpiod_line_release_bulk(lines);
gpiod_line_bulk_free(lines);
gpiod_line_bulk_free(evlines);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
return EXIT_SUCCESS;
}
mode->callback(&cbdata);
gpiod_line_release_bulk(lines);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
gpiod_line_bulk_free(lines);
free(offsets);
free(values);