@@ -13,7 +13,7 @@ namespace {
void chip_deleter(::gpiod_chip* chip)
{
- ::gpiod_chip_close(chip);
+ ::gpiod_chip_unref(chip);
}
} /* namespace */
@@ -1953,7 +1953,7 @@ static int gpiod_Chip_init(gpiod_ChipObject *self,
static void gpiod_Chip_dealloc(gpiod_ChipObject *self)
{
if (self->chip)
- gpiod_chip_close(self->chip);
+ gpiod_chip_unref(self->chip);
PyObject_Del(self);
}
@@ -1981,7 +1981,7 @@ static PyObject *gpiod_Chip_close(gpiod_ChipObject *self,
if (gpiod_ChipIsClosed(self))
return NULL;
- gpiod_chip_close(self->chip);
+ gpiod_chip_unref(self->chip);
self->chip = NULL;
Py_RETURN_NONE;
@@ -81,10 +81,18 @@ bool gpiod_is_gpiochip_device(const char *path) GPIOD_API;
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.
@@ -64,6 +64,8 @@ struct gpiod_line {
};
struct gpiod_chip {
+ int refcount;
+
struct gpiod_line **lines;
unsigned int num_lines;
@@ -297,6 +299,7 @@ struct gpiod_chip *gpiod_chip_open(const char *path)
chip->fd = fd;
chip->num_lines = info.lines;
+ chip->refcount = 1;
/*
* GPIO device must have a name - don't bother checking this field. In
@@ -324,11 +327,21 @@ err_close_fd:
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];
@@ -22,7 +22,7 @@
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. */
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
gpiod_chip_label(chip),
gpiod_chip_num_lines(chip));
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
free(entries[i]);
}
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
if (offset >= 0) {
printf("%s %u\n",
gpiod_chip_name(chip), offset);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
return EXIT_SUCCESS;
}
}
@@ -123,7 +123,7 @@ int main(int argc, char **argv)
printf("\n");
gpiod_line_release_bulk(lines);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
gpiod_line_bulk_free(lines);
free(values);
free(offsets);
@@ -230,7 +230,7 @@ int main(int argc, char **argv)
list_lines(chip);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
}
} else {
for (i = 0; i < argc; i++) {
@@ -240,7 +240,7 @@ int main(int argc, char **argv)
list_lines(chip);
- gpiod_chip_close(chip);
+ gpiod_chip_unref(chip);
}
}
@@ -306,7 +306,7 @@ done:
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;
}
@@ -305,7 +305,7 @@ int main(int argc, char **argv)
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);