commit 8285e71aecfd159643f1705f24709fc30a8cbda0 from: Stefan Sperling date: Mon Mar 11 14:11:07 2024 UTC request notification content from repo_write one at a time commit - 90dfaa0114b254eff2147735ed23dca09b571635 commit + 8285e71aecfd159643f1705f24709fc30a8cbda0 blob - 6e68ff331dae7881c9b5fdd240f869c658aedce6 blob + 2e293cfda482ac271343e8604d92b018614777f7 --- gotd/repo_write.c +++ gotd/repo_write.c @@ -1819,6 +1819,8 @@ render_notification(struct imsg *imsg, struct gotd_ims iev, imsg->fd); break; } + + /* TODO send GOTD_IMSG_NOTIFY */ free(refname); return err; blob - d62256a1b20427e1dd67b05242a133f23a7ee0ea blob + 133e70534548d1d8d4987921c6de3a96618c9da2 --- gotd/session.c +++ gotd/session.c @@ -55,6 +55,7 @@ struct gotd_session_notif { STAILQ_ENTRY(gotd_session_notif) entry; + int fd; enum gotd_notification_action action; char *refname; struct got_object_id old_id; @@ -460,6 +461,8 @@ queue_notification(struct got_object_id *old_id, struc if (notif == NULL) return got_error_from_errno("calloc"); + notif->fd = -1; + if (old_id == NULL) notif->action = GOTD_NOTIF_ACTION_CREATED; else if (new_id == NULL) @@ -485,8 +488,12 @@ done: return err; } +/* + * Forward notification content to the NOTIFY process. + * Request additional notifications from REPO_WRITE if any remain queued. + */ static const struct got_error * -send_notification(struct gotd_session_client *client, struct imsg *imsg) +forward_notification(struct gotd_session_client *client, struct imsg *imsg) { const struct got_error *err = NULL; struct gotd_imsgev *iev = &client->repo_child_iev; @@ -579,6 +586,63 @@ done: client->nref_updates == 0) client->flush_disconnect = 1; free(refname); + return err; +} + +/* Request notification content from REPO_WRITE process. */ +static const struct got_error * +request_notification(struct gotd_session_notif *notif) +{ + const struct got_error *err = NULL; + struct gotd_session_client *client = &gotd_session_client; + struct gotd_imsgev *iev = &client->repo_child_iev; + struct gotd_imsg_notification_content icontent; + struct ibuf *wbuf; + size_t len; + int fd; + + fd = got_opentempfd(); + if (fd == -1) + return got_error_from_errno("got_opentemp"); + + memset(&icontent, 0, sizeof(icontent)); + icontent.client_id = client->id; + + icontent.action = notif->action; + memcpy(&icontent.old_id, ¬if->old_id, sizeof(notif->old_id)); + memcpy(&icontent.new_id, ¬if->new_id, sizeof(notif->new_id)); + icontent.refname_len = strlen(notif->refname); + + len = sizeof(icontent) + icontent.refname_len; + wbuf = imsg_create(&iev->ibuf, GOTD_IMSG_NOTIFY, + gotd_session.proc_id, gotd_session.pid, len); + if (wbuf == NULL) { + err = got_error_from_errno("imsg_create NOTIFY"); + goto done; + } + if (imsg_add(wbuf, &icontent, sizeof(icontent)) == -1) { + err = got_error_from_errno("imsg_add NOTIFY"); + goto done; + } + if (imsg_add(wbuf, notif->refname, icontent.refname_len) == -1) { + err = got_error_from_errno("imsg_add NOTIFY"); + goto done; + } + + notif->fd = dup(fd); + if (notif->fd == -1) { + err = got_error_from_errno("dup"); + goto done; + } + + ibuf_fd_set(wbuf, fd); + fd = -1; + + imsg_close(&iev->ibuf, wbuf); + gotd_imsg_event_add(iev); +done: + if (err && fd != -1) + close(fd); return err; } @@ -591,6 +655,7 @@ update_ref(int *shut, struct gotd_session_client *clie struct got_reference *ref = NULL; struct gotd_imsg_ref_update iref; struct got_object_id old_id, new_id; + struct gotd_session_notif *notif; struct got_object_id *id = NULL; char *refname = NULL; size_t datalen; @@ -736,7 +801,18 @@ done: client->nref_updates--; if (client->nref_updates == 0) { send_refs_updated(client); - if (STAILQ_EMPTY(¬ifications)) + notif = STAILQ_FIRST(¬ifications); + if (notif) { + err = request_notification(notif); + if (err) { + /* + * Just log a warning. + * Notifications are best-effort. + */ + log_warn("could not send notification: " + "%s", err->msg); + } + } else client->flush_disconnect = 1; } @@ -864,7 +940,7 @@ session_dispatch_repo_child(int fd, short event, void err = update_ref(&shut, client, gotd_session.repo->path, &imsg); else if (do_notify) - err = send_notification(client, &imsg); + err = forward_notification(client, &imsg); if (err) log_warnx("uid %d: %s", client->euid, err->msg); } @@ -1839,6 +1915,8 @@ gotd_session_shutdown(void) while (!STAILQ_EMPTY(¬ifications)) { notif = STAILQ_FIRST(¬ifications); STAILQ_REMOVE_HEAD(¬ifications, entry); + if (notif->fd != -1) + close(notif->fd); free(notif->refname); free(notif); }