]> git.sur5r.net Git - openldap/commitdiff
ITS#5340: REP_ENTRY_MUSTFLUSH, rs_replace_entry(), rs_ensure_entry_modifiable()
authorHallvard Furuseth <hallvard@openldap.org>
Thu, 10 Dec 2009 00:07:34 +0000 (00:07 +0000)
committerHallvard Furuseth <hallvard@openldap.org>
Thu, 10 Dec 2009 00:07:34 +0000 (00:07 +0000)
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/slap.h

index 74cbf5db17898be740c9a4e68f407b37f3964d39..62ea62815edd4979654a9191dc84e872c5f55f81 100644 (file)
@@ -1514,6 +1514,10 @@ LDAP_SLAPD_F (int) get_alias_dn LDAP_P((
 /*
  * result.c
  */
+LDAP_SLAPD_F (void) rs_replace_entry LDAP_P(( Operation *op,
+       SlapReply *rs, slap_overinst *on, Entry *e ));
+LDAP_SLAPD_F (int) rs_ensure_entry_modifiable LDAP_P(( Operation *op,
+       SlapReply *rs, slap_overinst *on ));
 LDAP_SLAPD_F (void) slap_send_ldap_result LDAP_P(( Operation *op, SlapReply *rs ));
 LDAP_SLAPD_F (void) send_ldap_sasl LDAP_P(( Operation *op, SlapReply *rs ));
 LDAP_SLAPD_F (void) send_ldap_disconnect LDAP_P(( Operation *op, SlapReply *rs ));
index 33a5ee1c5f844e415a6e9cb125063f20c9e1b13f..e89090db148db22c007ba95ac7025a66ddc3f0f2 100644 (file)
@@ -132,6 +132,50 @@ slap_req2res( ber_tag_t tag )
        return tag;
 }
 
+#ifdef RS_ASSERT
+#elif 0 && defined LDAP_DEVEL /* FIXME: this should not crash. ITS#5340. */
+#define RS_ASSERT assert
+#else
+#define RS_ASSERT(cond) ((void) 0)
+#endif
+
+/* Set rs->sr_entry after obyeing and clearing sr_flags & REP_ENTRY_MASK. */
+void
+rs_replace_entry( Operation *op, SlapReply *rs, slap_overinst *on, Entry *e )
+{
+       slap_mask_t e_flags = rs->sr_flags & REP_ENTRY_MUSTFLUSH;
+
+       if ( e_flags && rs->sr_entry != NULL ) {
+               RS_ASSERT( e_flags != REP_ENTRY_MUSTFLUSH );
+               if ( !(e_flags & REP_ENTRY_MUSTRELEASE) ) {
+                       entry_free( rs->sr_entry );
+               } else if ( on != NULL ) {
+                       overlay_entry_release_ov( op, rs->sr_entry, 0, on );
+               } else {
+                       be_entry_release_rw( op, rs->sr_entry, 0 );
+               }
+       }
+       rs->sr_flags &= ~REP_ENTRY_MASK;
+       rs->sr_entry = e;
+}
+
+/*
+ * Ensure rs->sr_entry is modifiable, by duplicating it if necessary.
+ * Obey sr_flags.  Set REP_ENTRY_<MODIFIABLE, and MUSTBEFREED if duplicated>.
+ * Return nonzero if rs->sr_entry was replaced.
+ */
+int
+rs_ensure_entry_modifiable( Operation *op, SlapReply *rs, slap_overinst *on )
+{
+       if ( rs->sr_flags & REP_ENTRY_MODIFIABLE ) {
+               RS_ASSERT((rs->sr_flags & REP_ENTRY_MUSTFLUSH)==REP_ENTRY_MUSTBEFREED);
+               return 0;
+       }
+       rs_replace_entry( op, rs, on, entry_dup( rs->sr_entry ));
+       rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
+       return 1;
+}
+
 static long send_ldap_ber(
        Operation *op,
        BerElement *ber )
index 96d776eb98d5bda405338a0355ec3812552a7baf..779337e5d55f40244be0b9ec99488c33fbef7c25 100644 (file)
@@ -2097,6 +2097,7 @@ struct SlapReply {
 #define REP_ENTRY_MUSTBEFREED  0x0002U
 #define REP_ENTRY_MUSTRELEASE  0x0004U
 #define        REP_ENTRY_MASK          (REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED|REP_ENTRY_MUSTRELEASE)
+#define        REP_ENTRY_MUSTFLUSH     (REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED)
 
 #define REP_MATCHED_MUSTBEFREED        0x0010U
 #define        REP_MATCHED_MASK        (REP_MATCHED_MUSTBEFREED)