[bgpd] simplify peer refcounts, squash slow peer leak

2006-09-14 Paul Jakma <paul.jakma@sun.com>

	* (general) fix the peer refcount issue exposed by previous, by
	  just removing refcounting of peer threads, which is mostly
	  senseless as they're references leading from struct peer,
	  which peer_free cancels anyway. No need to muck around..
	* bgp_fsm.h: Just remove the refcounting from the various
	  TIMER/READ/WRITE/EVENT ON/OFF/ADD macros.
	* bgp_fsm.c: (bgp_stop) use BGP_EVENT_FLUSH, no refcounts attached
	  to events anymore.
	  (bgp_event) remove peer_unlock, events not refcounted.
	* bgpd.c: (peer_free) flush events before free.
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index 02aaf3a..393b00d 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -1,5 +1,18 @@
 2006-09-14 Paul Jakma <paul.jakma@sun.com>
 
+	* (general) fix the peer refcount issue exposed by previous, by
+	  just removing refcounting of peer threads, which is mostly
+	  senseless as they're references leading from struct peer,
+	  which peer_free cancels anyway. No need to muck around..
+	* bgp_fsm.h: Just remove the refcounting from the various
+	  TIMER/READ/WRITE/EVENT ON/OFF/ADD macros.
+	* bgp_fsm.c: (bgp_stop) use BGP_EVENT_FLUSH, no refcounts attached
+	  to events anymore.
+	  (bgp_event) remove peer_unlock, events not refcounted.
+	* bgpd.c: (peer_free) flush events before free.
+
+2006-09-14 Paul Jakma <paul.jakma@sun.com>
+
 	* (general) Fix some niggly issues around 'shutdown' and clearing
 	  by adding a Clearing FSM wait-state and a hidden 'Deleted'
 	  FSM state, to allow deleted peers to 'cool off' and hit 0
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index bdb6517..cc2b2c3 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -426,7 +426,6 @@
 {
   afi_t afi;
   safi_t safi;
-  unsigned int i;
   char orf_name[BUFSIZ];
 
   /* Increment Dropped count. */
@@ -500,10 +499,8 @@
   BGP_TIMER_OFF (peer->t_asorig);
   BGP_TIMER_OFF (peer->t_routeadv);
 
-  /* Delete all existing events of the peer,
-     and corresponding peer ref-count */
-  for (i = thread_cancel_event (master, peer); i > 0; i--)
-    peer_unlock (peer); /* thread event reference */
+  /* Delete all existing events of the peer */
+  BGP_EVENT_FLUSH (peer);
   
   /* Stream reset. */
   peer->packet_size = 0;
@@ -1101,6 +1098,5 @@
       bgp_timer_set (peer);
     }
   
-  peer_unlock (peer); /* bgp-event peer reference */
   return ret;
 }
diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h
index 0a5d371..c51bed3 100644
--- a/bgpd/bgp_fsm.h
+++ b/bgpd/bgp_fsm.h
@@ -25,77 +25,55 @@
 /* Macro for BGP read, write and timer thread.  */
 #define BGP_READ_ON(T,F,V)			\
   do {						\
-    if (!T)					\
-      {						\
-        peer_lock (peer);			\
-        THREAD_READ_ON(master,T,F,peer,V);	\
-      }						\
+    if (!(T) && (peer->status != Deleted))	\
+      THREAD_READ_ON(master,T,F,peer,V);	\
   } while (0)
 
 #define BGP_READ_OFF(T)				\
   do {						\
     if (T)					\
-      {						\
-        peer_unlock (peer);			\
-        THREAD_READ_OFF(T);			\
-      }						\
+      THREAD_READ_OFF(T);			\
   } while (0)
 
 #define BGP_WRITE_ON(T,F,V)			\
   do {						\
     if (!(T) && (peer->status != Deleted))	\
-      {						\
-        peer_lock (peer);			\
-        THREAD_WRITE_ON(master,(T),(F),peer,(V)); \
-      }						\
+      THREAD_WRITE_ON(master,(T),(F),peer,(V)); \
   } while (0)
     
 #define BGP_WRITE_OFF(T)			\
   do {						\
     if (T)					\
-      {						\
-        peer_unlock (peer);			\
-        THREAD_WRITE_OFF(T);			\
-      }						\
+      THREAD_WRITE_OFF(T);			\
   } while (0)
 
 #define BGP_TIMER_ON(T,F,V)			\
   do {						\
     if (!(T) && (peer->status != Deleted))	\
-      {						\
-        peer_lock (peer);			\
-        THREAD_TIMER_ON(master,(T),(F),peer,(V)); \
-      }						\
+      THREAD_TIMER_ON(master,(T),(F),peer,(V)); \
   } while (0)
 
 #define BGP_TIMER_OFF(T)			\
   do {						\
     if (T)					\
-      { 					\
-        peer_unlock (peer);			\
-        THREAD_TIMER_OFF(T);			\
-      }						\
+      THREAD_TIMER_OFF(T);			\
   } while (0)
 
 #define BGP_EVENT_ADD(P,E)			\
   do {						\
     if ((P)->status != Deleted)			\
-      {						\
-        peer_lock (peer); /* bgp event reference */ \
-        thread_add_event (master, bgp_event, (P), (E)); \
-      }						\
+      thread_add_event (master, bgp_event, (P), (E)); \
   } while (0)
 
-#define BGP_EVENT_DELETE(P)			\
+#define BGP_EVENT_FLUSH(P)			\
   do { 						\
-    peer_unlock (peer); /* bgp event peer reference */ \
     assert (peer); 				\
     thread_cancel_event (master, (P)); 		\
   } while (0)
 
 #define BGP_EVENT_FLUSH_ADD(P,E)	\
   do {					\
-    BGP_EVENT_DELETE(P);		\
+    BGP_EVENT_FLUSH(P);			\
     BGP_EVENT_ADD(P,E);			\
   } while (0)
 
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 733b33a..89f8262 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -695,6 +695,7 @@
   bgp_timer_set (peer);
   BGP_READ_OFF (peer->t_read);
   BGP_WRITE_OFF (peer->t_write);
+  BGP_EVENT_FLUSH (peer);
   
   if (peer->desc)
     XFREE (MTYPE_PEER_DESC, peer->desc);