suitcase

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

sc_eloop.c (5247B)


      1 // in order: pollfd (single entry), opaque (may be NULL), fdcb(descriptor_t*, void*)
      2 int descriptor_add (struct pollfd fd, void* opaque,
      3 		int (*fdcb)(descriptor_t*, short, void*))
      4 {
      5 	descriptor_t	*descriptor = NULL;
      6 
      7 	HASH_FIND_INT(Descriptortab, &(fd.fd), descriptor);
      8 	if (descriptor != NULL) return (errno = EEXIST, FALSE);
      9 	// Otherwise...
     10 	descriptor = malloc(sizeof(descriptor_t)); // strong pointer; if we cannot add this to the hash, we must free it
     11 	descriptor->fd = fd;
     12 	descriptor->opaque = opaque;
     13 	descriptor->fdcb = fdcb;
     14 	HASH_ADD_INT(Descriptortab, fd.fd, descriptor);
     15 	return 1; // if we are returning at all, we have succeeded.
     16 }
     17 
     18 // in order: descriptortab, pollfd (single entry)
     19 // returns true on success, false on nonexistent
     20 int descriptor_del (struct pollfd fd)
     21 {
     22 	descriptor_t	*descriptor = NULL;
     23 
     24 	HASH_FIND_INT(Descriptortab, &(fd.fd), descriptor);
     25 	if (descriptor == NULL) return FALSE;
     26 	// Otherwise...
     27 	HASH_DEL(Descriptortab, descriptor);
     28 	free(descriptor);
     29 	return TRUE; // if we are returning at all, we have succeeded.
     30 }
     31 
     32 // in order: processtab, process ID, opaque to be passed to the report callback, report callback
     33 int protege_add (pid_t pid, void* opaque,
     34 		int (*pdiecb)(process_t*, int, void*))
     35 {
     36 	process_t		*protege = NULL;
     37 
     38 	HASH_FIND(hh, Protegetab, &pid, sizeof(pid_t), protege);
     39 	if (protege != NULL) return (errno = EEXIST, FALSE);
     40 	// Otherwise...
     41 	protege = malloc(sizeof(descriptor_t)); // strong pointer; if we cannot add this to the hash, we must free it
     42 	protege->pid = pid;
     43 	protege->opaque = opaque;
     44 	protege->pdiecb = pdiecb;
     45 	HASH_ADD(hh, Protegetab, pid, sizeof(pid_t), protege);
     46 	return 1; // if we are returning at all, we have succeeded.
     47 }
     48 // in order: descriptortab, pollfd (single entry)
     49 // returns true on success, false on nonexistent
     50 int protege_del (pid_t pid)
     51 {
     52 	process_t		*protege = NULL;
     53 
     54 	HASH_FIND(hh, Protegetab, &(pid), sizeof(pid_t), protege);
     55 	if (protege == NULL) return (errno = ENOENT, FALSE);
     56 	HASH_DEL(Protegetab, protege);
     57 	free(protege);
     58 	return TRUE;
     59 }
     60 
     61 // in order: dnsqtab, process ID, opaque to be passed to the report callback, report callback
     62 int dnsq_add (uint16_t dnsqid, void* opaque, void* opaque2,
     63 		int (*qcb)(skadns_t*, dnsq_t*, void*, void*))
     64 {
     65 	dnsq_t			*dnsq = NULL;
     66 
     67 	HASH_FIND(hh, Dnsqtab, &dnsqid, sizeof(uint16_t), dnsq);
     68 	if (dnsq != NULL) return (errno = EEXIST, FALSE);
     69 	// Otherwise...
     70 	dnsq = malloc(sizeof(dnsq_t)); // strong pointer; if we cannot add this to the hash, we must free it
     71 	dnsq->dnsq = dnsqid;
     72 	dnsq->opaque = opaque;
     73 	dnsq->opaque2 = opaque2;
     74 	dnsq->qcb = qcb;
     75 	HASH_ADD(hh, Dnsqtab, dnsq, sizeof(uint16_t), dnsq);
     76 	return TRUE; // if we are returning at all, we have succeeded.
     77 }
     78 // in order: dnsqtab, pollfd (single entry)
     79 // returns true on success, false on nonexistent
     80 int dnsq_del (uint16_t dnsqid)
     81 {
     82 	dnsq_t			*dnsq = NULL;
     83 
     84 	HASH_FIND(hh, Dnsqtab, &(dnsqid), sizeof(uint16_t), dnsq);
     85 	if (dnsq == NULL) return (errno = ENOENT, FALSE);
     86 	HASH_DEL(Dnsqtab, dnsq);
     87 	free(dnsq);
     88 	return TRUE;
     89 }
     90 
     91 int run_fds (tain *deadline, tain *stamp)
     92 {
     93 	pfdAlloc		 fds = TA_ZERO; // pollfd
     94 	descriptor_t	 *des = NULL, *tmp = NULL;
     95 	struct pollfd *pfds = NULL; size_t pfdsiz = 0; size_t i = 0;
     96 	int pollret = 0;
     97 	HASH_ITER(hh, Descriptortab, des, tmp) {
     98 		if (!pfdalloc_catpfd(&fds, (des->fd))) temp_nomem();
     99 		des->fd.revents = 0;
    100 		++pfdsiz;
    101 	}
    102 	if (pfdsiz == 0) temp_runfds();
    103 	des = NULL; tmp = NULL;
    104 	pfds = (struct pollfd *)(fds.pfd);
    105 	pollret = iopause_stamp(pfds, pfdsiz, deadline, stamp);
    106 	// and then we wait for iopause to do its thing
    107 	// and then iopause wakes us up
    108 	switch (pollret) {
    109 		case 0:
    110 			// we literally have nothing to do. we return. this isn't an error state.
    111 			return pollret;
    112 			break;
    113 		case -1:
    114 			// errors AGAIN, FAULT, INTR, INVAL
    115 			switch (errno) {
    116 				case EAGAIN:
    117 					return 0; // we will just get called again
    118 					break;
    119 				case EFAULT:
    120 					temp_fault();
    121 					break;
    122 				case EINTR:
    123 					temp_intr(); // an uncaught signal has come our way
    124 					break;
    125 				case EINVAL:
    126 					temp_bug(); // invalid data
    127 					break;
    128 			}
    129 		default :
    130 			for (i = 0; i < pfdsiz; i++) {
    131 				HASH_FIND_INT(Descriptortab, &(pfds[i].fd), des);
    132 				if (des == NULL) {
    133 					temp_finderr(); // could not find the file descriptor in our tables - what kind of wiseguy do we have on here?
    134 				}
    135 				if (((pfds[i]).revents & POLLNVAL) != 0) {
    136 					// file descriptor is not known to the system; bug
    137 					temp_bug();
    138 				} else if ((pfds[i]).revents != 0) {
    139 					(*(des->fdcb))(des, (pfds[i]).revents, des->opaque);
    140 				}
    141 			}
    142 	}
    143 	// done with fds now? right, we return the number of FDs we processed.
    144 	free((fds.pfd));
    145 	return pollret;
    146 }
    147 
    148 int handledeadprocess ()
    149 {
    150 	process_t		*protege = NULL;
    151 	pid_t			pid = 0;
    152 	int				wstat;
    153 	while ((pid = wait_nohang(&wstat)) > 0) {
    154 		HASH_FIND(hh, Protegetab, &pid, sizeof(pid_t), protege);
    155 		if (protege == NULL) continue; // doesn't really matter
    156 		(*protege->pdiecb)(protege, wstat, protege->opaque);
    157 		protege_del(pid);
    158 	}
    159 	return TRUE;
    160 }
    161 
    162 int checksignals (descriptor_t *descr, short revents, void* unused)
    163 {
    164 	int sig;
    165 	sig = selfpipe_read();
    166 
    167 	switch (sig) {
    168 		case SIGCHLD:
    169 			return handledeadprocess();
    170 			break;
    171 		default :
    172 			return FALSE;// Advanced wiseguy shit
    173 	}
    174 }