degesch: get rid of repeating refcounting code
Macros aren't exactly spectacular but they work.
This commit is contained in:
		
							parent
							
								
									635c28820d
								
							
						
					
					
						commit
						5632eecd42
					
				
							
								
								
									
										87
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								degesch.c
									
									
									
									
									
								
							| @ -100,12 +100,43 @@ static struct config_item g_config_table[] = | ||||
| 		return false;                                                          \ | ||||
| 	BLOCK_END | ||||
| 
 | ||||
| static void user_unref (void *p); | ||||
| static void channel_unref (void *p); | ||||
| struct user; | ||||
| static void user_unref (struct user *self); | ||||
| 
 | ||||
| struct channel; | ||||
| static void channel_unref (struct channel *self); | ||||
| 
 | ||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||
| 
 | ||||
| // We need a few reference countable objects with support
 | ||||
| // for both strong and weak references
 | ||||
| 
 | ||||
| /// Callback just before a reference counted object is destroyed
 | ||||
| typedef void (*destroy_cb_fn) (void *object, void *user_data); | ||||
| 
 | ||||
| #define REF_COUNTABLE_HEADER                                                   \ | ||||
| 	size_t ref_count;                   /**< Reference count                */ \ | ||||
| 	destroy_cb_fn on_destroy;           /**< To remove any weak references  */ \ | ||||
| 	void *user_data;                    /**< User data for callbacks        */ | ||||
| 
 | ||||
| #define REF_COUNTABLE_METHODS(name)                                            \ | ||||
| 	static struct name *                                                       \ | ||||
| 	name ## _ref (struct name *self)                                           \ | ||||
| 	{                                                                          \ | ||||
| 		self->ref_count++;                                                     \ | ||||
| 		return self;                                                           \ | ||||
| 	}                                                                          \ | ||||
| 																			   \ | ||||
| 	static void                                                                \ | ||||
| 	name ## _unref (struct name *self)                                         \ | ||||
| 	{                                                                          \ | ||||
| 		if (--self->ref_count)                                                 \ | ||||
| 			return;                                                            \ | ||||
| 		if (self->on_destroy)                                                  \ | ||||
| 			self->on_destroy (self, self->user_data);                          \ | ||||
| 		name ## _destroy (self);                                               \ | ||||
| 	} | ||||
| 
 | ||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||
| 
 | ||||
| struct user_channel | ||||
| @ -123,9 +154,8 @@ user_channel_new (void) | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| user_channel_destroy (void *p) | ||||
| user_channel_destroy (struct user_channel *self) | ||||
| { | ||||
| 	struct user_channel *self = p; | ||||
| 	channel_unref (self->channel); | ||||
| 	free (self); | ||||
| } | ||||
| @ -137,10 +167,7 @@ user_channel_destroy (void *p) | ||||
| 
 | ||||
| struct user | ||||
| { | ||||
| 	size_t ref_count;                   ///< Reference count
 | ||||
| 
 | ||||
| 	destroy_cb_fn on_destroy;           ///< To remove any weak references
 | ||||
| 	void *user_data;                    ///< User data for callbacks
 | ||||
| 	REF_COUNTABLE_HEADER | ||||
| 
 | ||||
| 	// TODO: eventually a reference to the server
 | ||||
| 
 | ||||
| @ -162,29 +189,13 @@ user_new (void) | ||||
| static void | ||||
| user_destroy (struct user *self) | ||||
| { | ||||
| 	if (self->on_destroy) | ||||
| 		self->on_destroy (self, self->user_data); | ||||
| 
 | ||||
| 	free (self->nickname); | ||||
| 	LIST_FOR_EACH (struct user_channel, iter, self->channels) | ||||
| 		user_channel_destroy (iter); | ||||
| 	free (self); | ||||
| } | ||||
| 
 | ||||
| static struct user * | ||||
| user_ref (struct user *self) | ||||
| { | ||||
| 	self->ref_count++; | ||||
| 	return self; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| user_unref (void *p) | ||||
| { | ||||
| 	struct user *self = p; | ||||
| 	if (!--self->ref_count) | ||||
| 		user_destroy (self); | ||||
| } | ||||
| REF_COUNTABLE_METHODS (user) | ||||
| 
 | ||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||
| 
 | ||||
| @ -204,9 +215,8 @@ channel_user_new (void) | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| channel_user_destroy (void *p) | ||||
| channel_user_destroy (struct channel_user *self) | ||||
| { | ||||
| 	struct channel_user *self = p; | ||||
| 	user_unref (self->user); | ||||
| 	free (self->modes); | ||||
| 	free (self); | ||||
| @ -219,10 +229,7 @@ channel_user_destroy (void *p) | ||||
| 
 | ||||
| struct channel | ||||
| { | ||||
| 	size_t ref_count;                   ///< Reference count
 | ||||
| 
 | ||||
| 	destroy_cb_fn on_destroy;           ///< To remove any weak references
 | ||||
| 	void *user_data;                    ///< User data for callbacks
 | ||||
| 	REF_COUNTABLE_HEADER | ||||
| 
 | ||||
| 	// TODO: eventually a reference to the server
 | ||||
| 
 | ||||
| @ -244,9 +251,6 @@ channel_new (void) | ||||
| static void | ||||
| channel_destroy (struct channel *self) | ||||
| { | ||||
| 	if (self->on_destroy) | ||||
| 		self->on_destroy (self, self->user_data); | ||||
| 
 | ||||
| 	free (self->name); | ||||
| 	free (self->mode); | ||||
| 	free (self->topic); | ||||
| @ -255,20 +259,7 @@ channel_destroy (struct channel *self) | ||||
| 	free (self); | ||||
| } | ||||
| 
 | ||||
| static struct channel * | ||||
| channel_ref (struct channel *self) | ||||
| { | ||||
| 	self->ref_count++; | ||||
| 	return self; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| channel_unref (void *p) | ||||
| { | ||||
| 	struct channel *self = p; | ||||
| 	if (!--self->ref_count) | ||||
| 		channel_destroy (self); | ||||
| } | ||||
| REF_COUNTABLE_METHODS (channel) | ||||
| 
 | ||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user