operation->callback(operation);
else
complete_all(&operation->completion);
+ gb_operation_put(operation);
}
/*
request_size, response_size);
}
+/*
+ * Get an additional reference on an operation.
+ */
+void gb_operation_get(struct gb_operation *operation)
+{
+ kref_get(&operation->kref);
+}
+
/*
* Destroy a previously created operation.
*/
kmem_cache_free(gb_operation_cache, operation);
}
+/*
+ * Drop a reference on an operation, and destroy it when the last
+ * one is gone.
+ */
void gb_operation_put(struct gb_operation *operation)
{
if (!WARN_ON(!operation))
return -ENOTCONN;
/*
- * XXX
- * I think the order of operations is going to be
- * significant, and if so, we may need a mutex to surround
- * setting the operation id and submitting the buffer.
+ * First, get an extra reference on the operation.
+ * It'll be dropped when the operation completes.
*/
+ gb_operation_get(operation);
+
operation->callback = callback;
gb_pending_operation_insert(operation);
struct gb_operation *gb_operation_create(struct gb_connection *connection,
u8 type, size_t request_size,
size_t response_size);
-struct gb_operation *gb_operation_get(struct gb_operation *operation);
+void gb_operation_get(struct gb_operation *operation);
void gb_operation_put(struct gb_operation *operation);
static inline void gb_operation_destroy(struct gb_operation *operation)
{