+# $obj must respond to ->on_inbox_unlock, which takes Inbox ($self) as an arg
+sub subscribe_unlock {
+ my ($self, $ident, $obj) = @_;
+ $self->{unlock_subs}->{$ident} = $obj;
+}
+
+sub unsubscribe_unlock {
+ my ($self, $ident) = @_;
+ delete $self->{unlock_subs}->{$ident};
+}
+
+sub check_inodes ($) {
+ my ($self) = @_;
+ for (qw(over mm)) { # TODO: search
+ $self->{$_}->check_inodes if $self->{$_};
+ }
+}
+
+# called by inotify
+sub on_unlock {
+ my ($self) = @_;
+ check_inodes($self);
+ my $subs = $self->{unlock_subs} or return;
+ for (values %$subs) {
+ eval { $_->on_inbox_unlock($self) };
+ warn "E: $@ ($self->{inboxdir})\n" if $@;
+ }
+}
+
+sub uidvalidity { $_[0]->{uidvalidity} //= $_[0]->mm->created_at }
+
+sub eidx_key { $_[0]->{newsgroup} // $_[0]->{inboxdir} }
+