job.c
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:7k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2.  *  Openmysee
  3.  *
  4.  *  This program is free software; you can redistribute it and/or modify
  5.  *  it under the terms of the GNU General Public License as published by
  6.  *  the Free Software Foundation; either version 2 of the License, or
  7.  *  (at your option) any later version.
  8.  *
  9.  *  This program is distributed in the hope that it will be useful,
  10.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  *  GNU General Public License for more details.
  13.  *
  14.  *  You should have received a copy of the GNU General Public License
  15.  *  along with this program; if not, write to the Free Software
  16.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17.  *
  18.  */
  19.  
  20. #include "echo.h"
  21. struct JobDes *JobCacheHead;
  22. static int JobCacheCount;
  23. extern int JobHighWater;
  24. inline struct JobDes *newJob ()
  25. {
  26. struct JobDes *p = JobCacheHead;
  27. if (p)
  28. {
  29. JobCacheHead = p->next;
  30. JobCacheCount --;
  31. p->start = p->len = 0;
  32. p->pc = NULL;
  33. p->p = NULL;
  34. }
  35. else
  36. p = calloc (1, sizeof (struct JobDes));
  37. p->blockid = -1;
  38. return p;
  39. }
  40. void inline setblockId (struct JobDes *pj, int id)
  41. {
  42. pj->blockid = id;
  43. }
  44. void freeJobCache ()
  45. {
  46. struct JobDes *p, *nextp;
  47. for (p=JobCacheHead; p; p=nextp)
  48. {
  49. nextp = p->next;
  50. free (p);
  51. }
  52. JobCacheHead = NULL;
  53. JobCacheCount = 0;
  54. }
  55. static struct JobDes *freeJob (struct JobDes *head, struct JobDes *p)
  56. {
  57. if (p == NULL) return head;
  58. if (p->pc) p->pc->numjob --;
  59. p->p->numjob --;
  60. if (head == p)
  61. head = p->next;
  62. if (head == p)
  63. head = NULL;
  64. p->prev->next = p->next;
  65. p->next->prev = p->prev;
  66. if (JobCacheCount > JobHighWater)
  67. {
  68. free (p);
  69. } else
  70. {
  71. p->next = JobCacheHead;
  72. JobCacheHead = p;
  73. JobCacheCount ++;
  74. }
  75. return head;
  76. }
  77. inline struct JobDes *findEnoughBuffer (struct Session *q, struct Channel *pc, int size)
  78. {
  79. struct JobDes *p = q->head;
  80. if (p == NULL) return NULL;
  81. do
  82. {
  83. if (p->pc == pc && p->blockid == -1 && MAX_MSG_SIZE - p->len - p->start > size)
  84. return p;
  85. p = p->next;
  86. } while (p!=q->head);
  87. return NULL;
  88. }
  89. inline char *getJobBuffer (struct JobDes *p, int *max)
  90. {
  91. *max = MAX_MSG_SIZE - p->len - p->start;
  92. return p->buffer+p->start+p->len;
  93. }
  94. void addJob (struct Session *q, struct Channel *pc, struct JobDes *n)
  95. {
  96. n->p = q;
  97. n->pc = pc;
  98. if (q->head == NULL)
  99. {
  100. q->head = n;
  101. n->next = n;
  102. n->prev = n;
  103. } else
  104. {
  105. n->next = q->head;
  106. n->prev = q->head->prev;
  107. n->next->prev = n;
  108. n->prev->next = n;
  109. }
  110. q->numjob ++;
  111. if (pc) pc->numjob ++;
  112. }
  113. void deleteJob (struct Session *q, struct Channel *pc, int *ids, int num)
  114. {
  115. int i;
  116. struct JobDes *p, *nextp;
  117. if ((p=q->head) == NULL) return;
  118. for (;;)
  119. {
  120. nextp = p->next;
  121. if (p->pc == pc)
  122. {
  123. for (i=0; i<num; i++)
  124. {
  125. if (ids[i] == p->blockid)
  126. {
  127. q->head = freeJob (q->head, p);
  128. break;
  129. }
  130. }
  131. }
  132. if (q->head == NULL || q->head == nextp)
  133. break;
  134. p = nextp;
  135. }
  136. }
  137. void deleteAll (struct Session *q)
  138. {
  139. struct JobDes *p, *nextp;
  140. if ((p=q->head) == NULL) return;
  141. for (;;)
  142. {
  143. nextp = p->next;
  144. q->head = freeJob (q->head, p);
  145. if (q->head == NULL)
  146. break;
  147. p = nextp;
  148. }
  149. }
  150. void deleteChannel (struct Session *q, struct Channel *pc)
  151. {
  152. struct JobDes *p, *nextp;
  153. if ((p=q->head) == NULL) return;
  154. for (;;)
  155. {
  156. nextp = p->next;
  157. if (p->pc == pc)
  158. q->head = freeJob (q->head, p);
  159. if (q->head == NULL || q->head == nextp)
  160. break;
  161. p = nextp;
  162. }
  163. }
  164. int processJobs (struct Session *q)
  165. {
  166. struct JobDes *p, *nextp;
  167. unsigned int total = 0, this_write;
  168. if ((p=q->head) == NULL) return 0;
  169. for (;;)
  170. {
  171. nextp = p->next;
  172. if ((this_write = write (q->socket, p->buffer+p->start, p->len))
  173. <= 0)
  174. {
  175. PDEBUG ("Error in write in session %d.n", q->socket);
  176. return -1;
  177. }
  178. p->len -= this_write;
  179. p->start += this_write;
  180. total += this_write;
  181. if (p->len == 0)
  182. q->head = freeJob (q->head, p);
  183. else
  184. break;
  185. if (q->head == NULL)
  186. break;
  187. p = nextp;
  188. }
  189. return total;
  190. }
  191. #ifdef __TEST_JOB
  192. main ()
  193. {
  194. struct Session *q = calloc (sizeof (*q), 1);
  195. struct Channel *qc = calloc (sizeof (*qc), 1);
  196. struct JobDes *p;
  197. int array[2];
  198. assert (q);
  199. p = newJob ();
  200. if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
  201. || p->len != 0 || p->p != NULL)
  202. assert (0);
  203. setblockId (p, 10);
  204. if (p->blockid != 10)
  205. assert (0);
  206. addJob (q, qc, p);
  207. // a new job
  208. p = newJob ();
  209. if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
  210. || p->len != 0 || p->p != NULL)
  211. assert (0);
  212. setblockId (p, 20);
  213. if (p->blockid != 20)
  214. assert (0);
  215. addJob (q, NULL, p);
  216. // a new job
  217. p = newJob ();
  218. if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
  219. || p->len != 0 || p->p != NULL)
  220. assert (0);
  221. setblockId (p, 30);
  222. if (p->blockid != 30)
  223. assert (0);
  224. addJob (q, qc, p);
  225. // a new job
  226. p = newJob ();
  227. if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
  228. || p->len != 0 || p->p != NULL)
  229. assert (0);
  230. setblockId (p, 40);
  231. if (p->blockid != 40)
  232. assert (0);
  233. addJob (q, NULL, p);
  234. // a new job
  235. p = newJob ();
  236. if (p == NULL || p->blockid != -1 || p->pc != NULL || p->start != 0
  237. || p->len != 0 || p->p != NULL)
  238. assert (0);
  239. setblockId (p, 50);
  240. if (p->blockid != 50)
  241. assert (0);
  242. addJob (q, qc, p);
  243. if (q->head == NULL || q->head->blockid != 10 || q->head->next == NULL
  244. || q->head->next->blockid != 20
  245. || q->head->next->next == NULL
  246. || q->head->next->next->blockid != 30
  247. || q->head->next->next->next == NULL
  248. || q->head->next->next->next->blockid != 40
  249. || q->head->next->next->next->next == NULL
  250. || q->head->next->next->next->next->blockid != 50
  251. || q->head->next->next->next->next->next == NULL
  252. || q->head->next->next->next->next->next->blockid != 10)
  253. assert (0);
  254. array[0] = 10;
  255. array[1] = 20;
  256. deleteJob (q, qc, array, 2);
  257. if (q->head == NULL || q->head->blockid != 20 || q->head->next == NULL
  258. || q->head->next->blockid != 30
  259. || q->head->next->next == NULL
  260. || q->head->next->next->blockid != 40
  261. || q->head->next->next->next == NULL
  262. || q->head->next->next->next->blockid != 50
  263. || q->head->next->next->next->next == NULL
  264. || q->head->next->next->next->next->blockid != 20)
  265. assert (0);
  266. deleteChannel (q, qc);
  267. if (q->head == NULL || q->head->blockid != 20 || q->head->next == NULL
  268. || q->head->next->blockid != 40)
  269. assert (0);
  270. deleteAll (q);
  271. if (q->head != NULL)
  272. assert (0);
  273. free (q);
  274. free (qc);
  275. freeJobCache ();
  276. }
  277. #endif