📄 job.c
字号:
/*
* Openmysee
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "echo.h"
struct JobDes *JobCacheHead;
static int JobCacheCount;
extern int JobHighWater;
inline struct JobDes *newJob ()
{
struct JobDes *p = JobCacheHead;
if (p)
{
JobCacheHead = p->next;
JobCacheCount --;
p->start = p->len = 0;
p->pc = NULL;
p->p = NULL;
}
else
p = calloc (1, sizeof (struct JobDes));
p->blockid = -1;
return p;
}
void inline setblockId (struct JobDes *pj, int id)
{
pj->blockid = id;
}
void freeJobCache ()
{
struct JobDes *p, *nextp;
for (p=JobCacheHead; p; p=nextp)
{
nextp = p->next;
free (p);
}
JobCacheHead = NULL;
JobCacheCount = 0;
}
static struct JobDes *freeJob (struct JobDes *head, struct JobDes *p)
{
if (p == NULL) return head;
if (p->pc) p->pc->numjob --;
p->p->numjob --;
if (head == p)
head = p->next;
if (head == p)
head = NULL;
p->prev->next = p->next;
p->next->prev = p->prev;
if (JobCacheCount > JobHighWater)
{
free (p);
} else
{
p->next = JobCacheHead;
JobCacheHead = p;
JobCacheCount ++;
}
return head;
}
inline struct JobDes *findEnoughBuffer (struct Session *q, struct Channel *pc, int size)
{
struct JobDes *p = q->head;
if (p == NULL) return NULL;
do
{
if (p->pc == pc && p->blockid == -1 && MAX_MSG_SIZE - p->len - p->start > size)
return p;
p = p->next;
} while (p!=q->head);
return NULL;
}
inline char *getJobBuffer (struct JobDes *p, int *max)
{
*max = MAX_MSG_SIZE - p->len - p->start;
return p->buffer+p->start+p->len;
}
void addJob (struct Session *q, struct Channel *pc, struct JobDes *n)
{
n->p = q;
n->pc = pc;
if (q->head == NULL)
{
q->head = n;
n->next = n;
n->prev = n;
} else
{
n->next = q->head;
n->prev = q->head->prev;
n->next->prev = n;
n->prev->next = n;
}
q->numjob ++;
if (pc) pc->numjob ++;
}
void deleteJob (struct Session *q, struct Channel *pc, int *ids, int num)
{
int i;
struct JobDes *p, *nextp;
if ((p=q->head) == NULL) return;
for (;;)
{
nextp = p->next;
if (p->pc == pc)
{
for (i=0; i<num; i++)
{
if (ids[i] == p->blockid)
{
q->head = freeJob (q->head, p);
break;
}
}
}
if (q->head == NULL || q->head == nextp)
break;
p = nextp;
}
}
void deleteAll (struct Session *q)
{
struct JobDes *p, *nextp;
if ((p=q->head) == NULL) return;
for (;;)
{
nextp = p->next;
q->head = freeJob (q->head, p);
if (q->head == NULL)
break;
p = nextp;
}
}
void deleteChannel (struct Session *q, struct Channel *pc)
{
struct JobDes *p, *nextp;
if ((p=q->head) == NULL) return;
for (;;)
{
nextp = p->next;
if (p->pc == pc)
q->head = freeJob (q->head, p);
if (q->head == NULL || q->head == nextp)
break;
p = nextp;
}
}
int processJobs (struct Session *q)
{
struct JobDes *p, *nextp;
unsigned int total = 0, this_write;
if ((p=q->head) == NULL) return 0;
for (;;)
{
nextp = p->next;
if ((this_write = write (q->socket, p->buffer+p->start, p->len))
<= 0)
{
PDEBUG ("Error in write in session %d.\n", q->socket);
return -1;
}
p->len -= this_write;
p->start += this_write;
total += this_write;
if (p->len == 0)
q->head = freeJob (q->head, p);
else
break;
if (q->head == NULL)
break;
p = nextp;
}
return total;
}
#ifdef __TEST_JOB
main ()
{
struct Session *q = calloc (sizeof (*q), 1);
struct Channel *qc = calloc (sizeof (*qc), 1);
struct JobDes *p;
int array[2];
assert (q);
p = newJob ();
if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
|| p->len != 0 || p->p != NULL)
assert (0);
setblockId (p, 10);
if (p->blockid != 10)
assert (0);
addJob (q, qc, p);
// a new job
p = newJob ();
if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
|| p->len != 0 || p->p != NULL)
assert (0);
setblockId (p, 20);
if (p->blockid != 20)
assert (0);
addJob (q, NULL, p);
// a new job
p = newJob ();
if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
|| p->len != 0 || p->p != NULL)
assert (0);
setblockId (p, 30);
if (p->blockid != 30)
assert (0);
addJob (q, qc, p);
// a new job
p = newJob ();
if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
|| p->len != 0 || p->p != NULL)
assert (0);
setblockId (p, 40);
if (p->blockid != 40)
assert (0);
addJob (q, NULL, p);
// a new job
p = newJob ();
if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
|| p->len != 0 || p->p != NULL)
assert (0);
setblockId (p, 50);
if (p->blockid != 50)
assert (0);
addJob (q, qc, p);
if (q->head == NULL || q->head->blockid != 10 || q->head->next == NULL
|| q->head->next->blockid != 20
|| q->head->next->next == NULL
|| q->head->next->next->blockid != 30
|| q->head->next->next->next == NULL
|| q->head->next->next->next->blockid != 40
|| q->head->next->next->next->next == NULL
|| q->head->next->next->next->next->blockid != 50
|| q->head->next->next->next->next->next == NULL
|| q->head->next->next->next->next->next->blockid != 10)
assert (0);
array[0] = 10;
array[1] = 20;
deleteJob (q, qc, array, 2);
if (q->head == NULL || q->head->blockid != 20 || q->head->next == NULL
|| q->head->next->blockid != 30
|| q->head->next->next == NULL
|| q->head->next->next->blockid != 40
|| q->head->next->next->next == NULL
|| q->head->next->next->next->blockid != 50
|| q->head->next->next->next->next == NULL
|| q->head->next->next->next->next->blockid != 20)
assert (0);
deleteChannel (q, qc);
if (q->head == NULL || q->head->blockid != 20 || q->head->next == NULL
|| q->head->next->blockid != 40)
assert (0);
deleteAll (q);
if (q->head != NULL)
assert (0);
free (q);
free (qc);
freeJobCache ();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -