Explorar o código

dialog: added cleanup of expired remote profiles via internal timer

Daniel-Constantin Mierla %!s(int64=11) %!d(string=hai) anos
pai
achega
157a50f7fe
Modificáronse 3 ficheiros con 53 adicións e 0 borrados
  1. 1 0
      modules/dialog/dialog.c
  2. 45 0
      modules/dialog/dlg_profile.c
  3. 7 0
      modules/dialog/dlg_profile.h

+ 1 - 0
modules/dialog/dialog.c

@@ -1235,6 +1235,7 @@ void dlg_ka_timer_exec(unsigned int ticks, void* param)
 void dlg_clean_timer_exec(unsigned int ticks, void* param)
 {
 	dlg_clean_run(ticks);
+	remove_expired_remote_profiles(time(NULL));
 }
 
 static int fixup_dlg_bye(void** param, int param_no)

+ 45 - 0
modules/dialog/dlg_profile.c

@@ -319,6 +319,50 @@ inline static unsigned int calc_hash_profile(str *value1, str *value2,
 }
 
 
+/*!
+ * \brief Remove remote profile items that are expired
+ * \param te expiration time
+ */
+void remove_expired_remote_profiles(time_t te)
+{
+	struct dlg_profile_table *profile;
+	struct dlg_profile_entry *p_entry;
+	struct dlg_profile_hash *lh;
+	struct dlg_profile_hash *kh;
+	int i;
+
+	for( profile=profiles ; profile ; profile=profile->next ) {
+		if(profile->flags&FLAG_PROFILE_REMOTE) {
+			for(i=0; i<profile->size; i++) {
+				/* space for optimization */
+				lock_get(&profile->lock);
+				p_entry = &profile->entries[i];
+				lh = p_entry->first;
+				while(lh) {
+					kh = lh->next;
+					if(lh->dlg==NULL && lh->expires>0 && lh->expires<te) {
+						/* last element on the list? */
+						if (lh==lh->next) {
+							p_entry->first = NULL;
+						} else {
+							if (p_entry->first==lh)
+								p_entry->first = lh->next;
+							lh->next->prev = lh->prev;
+							lh->prev->next = lh->next;
+						}
+						lh->next = lh->prev = NULL;
+						if(lh->linker) shm_free(lh->linker);
+						p_entry->content--;
+						return;
+					}
+					lh = kh;
+				}
+				lock_release(&profile->lock);
+			}
+		}
+	}
+}
+
 /*!
  * \brief Remove profile
  * \param profile pointer to profile
@@ -611,6 +655,7 @@ int dlg_add_profile(dlg_cell_t *dlg, str *value, struct dlg_profile_table *profi
 	} else {
 		vkey.s = linker->hash_linker.puid;
 		vkey.len = linker->hash_linker.puid_len;
+		profile->flags |= FLAG_PROFILE_REMOTE;
 		link_profile(linker, &vkey);
 	}
 	return 0;

+ 7 - 0
modules/dialog/dlg_profile.h

@@ -76,12 +76,14 @@ typedef struct dlg_profile_entry {
 	unsigned int content; /*!< content of the entry */
 } dlg_profile_entry_t;
 
+#define FLAG_PROFILE_REMOTE	1
 
 /*! dialog profile table */
 typedef struct dlg_profile_table {
 	str name; /*!< name of the dialog profile */
 	unsigned int size; /*!< size of the dialog profile */
 	unsigned int has_value; /*!< 0 for profiles without value, otherwise it has a value */
+	int flags; /*!< flags related to the profile */
 	gen_lock_t lock; /*! lock for concurrent access */
 	struct dlg_profile_entry *entries;
 	struct dlg_profile_table *next;
@@ -228,4 +230,9 @@ int dlg_profiles_to_json(dlg_cell_t *dlg, srjson_doc_t *jdoc);
  */
 int dlg_json_to_profiles(dlg_cell_t *dlg, srjson_doc_t *jdoc);
 
+/*!
+ * \brief Remove expired remove profiles
+ */
+void remove_expired_remote_profiles(time_t te);
+
 #endif