diff --git a/TODO b/TODO
index 21d3fd5..990bb26 100644
--- a/TODO
+++ b/TODO
@@ -27,3 +27,51 @@ VERY BIG TODO:
* also concurrent connection don't seem to make a problem.
* keep-alive alone again don't seem to be a problem...
!!!! if both are active something is screwed up.... !!!!
+
+- at least some of the problems result in something that I think
+ is a bug in the glibc implementation of tdelete.
+
+ Under some circumstances tdelete does not search the whole tree.
+ Here comes some debug output of the code...
+
+ This shows a code fragment that tries to remove a no longer
+ needed asset from the asset_pool.
+
+ DEBUG: pool release asset --./assets/image/waldschrat.jpg--
+
+ Twalk over all elements in the tree:
+
+ DEBUG: ./assets/image/waldschrat.jpg(1910357807899405601) => 0xe378a8
+ DEBUG: ./assets/js/jquery.js(10519512221325982142) => 0x10d3638
+
+ Output of each call to tDelete comparison function:
+ (Notice that the searched asset hash was in the previous Twalk.
+
+ DEBUG: search asset hash: 1910357807899405601
+ DEBUG: found: 10519512221325982142, key: ./assets/js/jquery.js
+ DEBUG: !!!!! NOT FOUND !!!!!!!
+ DEBUG: find results in (nil)
+
+ Repeated 2 times if non was found...
+
+ DEBUG: search asset hash: 1910357807899405601
+ DEBUG: found: 10519512221325982142, key: ./assets/js/jquery.js
+ DEBUG: !!!!! NOT FOUND !!!!!!!
+ DEBUG: find results in (nil)
+ DEBUG: search asset hash: 1910357807899405601
+ DEBUG: found: 10519512221325982142, key: ./assets/js/jquery.js
+ DEBUG: !!!!! NOT FOUND !!!!!!!
+ DEBUG: find results in (nil)
+ ===
+
+ Again a twalk over all elements...
+
+ DEBUG: ./assets/image/waldschrat.jpg(1910357807899405601) => 0xe378a8
+ DEBUG: ./assets/js/jquery.js(10519512221325982142) => 0x10d3638
+
+ Final statement...
+
+ DEBUG delete 0xe378a8, parent was (nil)
+
+ So, it looks like I should build my own tree implementation...
+ well in fact it seems that I have to!
diff --git a/include/http/response.h b/include/http/response.h
index ea89240..b2e56ba 100644
--- a/include/http/response.h
+++ b/include/http/response.h
@@ -51,7 +51,7 @@ HttpResponse httpResponseMe();
HttpResponse httpResponseLoginForm();
HttpResponse httpResponseRandval(time_t, int);
HttpResponse httpResponseSession(Session);
-HttpResponse httpResponseAsset(Asset);
+HttpResponse httpResponseAsset(const char *, size_t);
#endif // __HTTP_RESPONSE_H__
diff --git a/src/asset/asset.c b/src/asset/asset.c
index 2f9628f..2aacc41 100644
--- a/src/asset/asset.c
+++ b/src/asset/asset.c
@@ -20,6 +20,10 @@
* along with this program. If not, see .
*/
+// for debug
+#include
+
+
#include
// for mmap
@@ -97,9 +101,13 @@ assetCtor(void * _this, va_list * params)
NULL, this->size, PROT_READ, MAP_PRIVATE, this->handle, 0);
if (MAP_FAILED == this->data) {
+ close(this->handle);
return -1;
}
+ printf("DEBUG file mapped from %p to %p\n",
+ this->data, this->data + this->size);
+
this->ref_count = 1;
return 0;
@@ -112,7 +120,7 @@ static void assetDtor(void * _this) {
munmap(this->data, this->size);
}
- if (0 != this->handle) {
+ if (0 < this->handle) {
close(this->handle);
}
}
diff --git a/src/asset/pool.c b/src/asset/pool.c
index 364993c..1c07e20 100644
--- a/src/asset/pool.c
+++ b/src/asset/pool.c
@@ -20,6 +20,9 @@
* along with this program. If not, see .
*/
+// for debugging
+#include
+
// for size_t
#include
@@ -44,6 +47,8 @@ assetPoolGet(const char * path, size_t npath)
{
Asset asset = NULL;
+ printf("DEBUG: pool get asset --%s--\n", path);
+
if (NULL == asset_pool) {
asset_pool = new(Hash);
} else {
@@ -52,9 +57,12 @@ assetPoolGet(const char * path, size_t npath)
if (NULL == asset) {
asset = new(Asset, path, npath);
+ printf("DEBUG create asset %p\n", asset);
hashAdd(asset_pool, asset);
} else {
+ printf("DEBUG found asset %p\n", asset);
asset->ref_count++;
+ printf("DEBUG increase ref_count to %zu\n", asset->ref_count);
}
return asset;
@@ -63,19 +71,22 @@ assetPoolGet(const char * path, size_t npath)
size_t
assetPoolRelease(Asset asset)
{
- if (asset->ref_count <= 1) {
- hashDelete( asset_pool, asset->fname, asset->nfname);
+ printf("DEBUG: pool release asset --%s--\n", asset->fname);
- if (NULL != asset) {
- delete(asset);
- }
-
- return 0;
- } else {
+ if (asset->ref_count > 1) {
asset->ref_count--;
-
+ printf("DEBUG decrease ref_count to %zu\n", asset->ref_count);
return asset->ref_count;
}
+
+ if (NULL != asset) {
+ Asset found = (Asset)hashDelete(
+ asset_pool, asset->fname, asset->nfname);
+ printf("DEBUG delete %p, parent was %p\n", asset, found);
+ delete(asset);
+ }
+
+ return 0;
}
void
diff --git a/src/hash/delete.c b/src/hash/delete.c
index a14c70c..cadcf31 100644
--- a/src/hash/delete.c
+++ b/src/hash/delete.c
@@ -20,9 +20,12 @@
* along with this program. If not, see .
*/
+#include
+
#include
#include
+#include "asset.h"
#include "hash.h"
#include "utils/hash.h"
@@ -31,25 +34,61 @@ inline
int
hashDeleteComp(const void * a, const void * b)
{
+ if (_Asset == GET_CLASS(b)) {
+ Asset data = (Asset)b;
+ printf("DEBUG: search asset hash: %lu\n",
+ *(const unsigned long*)a);
+ printf("DEBUG: found: %lu, key: %s\n",
+ data->hash, data->fname);
+ }
+
return hashableGetHash((void*)b) - *(const unsigned long*)a;
}
+void
+action(const void *nodep, const VISIT which, const int depth)
+{
+ void * datap = *(void **)nodep;
+
+ if (_Asset == GET_CLASS(datap)) {
+ Asset data = (Asset)datap;
+
+ switch (which) {
+ case preorder:
+ break;
+ case postorder:
+ printf("DEBUG: %s(%lu) => %p\n", data->fname, data->hash, data);
+ break;
+ case endorder:
+ break;
+ case leaf:
+ printf("DEBUG: %s(%lu) => %p\n", data->fname, data->hash, data);
+ break;
+ }
+ }
+}
+
void *
hashDelete(Hash this, const char * search, size_t nsearch)
{
unsigned long hash = sdbm((const unsigned char *)search, nsearch);
- void ** _found = tfind(&hash, &(this->root), hashDeleteComp);
- void * found;
+ void * found = NULL;
+ int count = 0;
- if (NULL != _found) {
- found = *_found;
- } else {
- found = NULL;
+ twalk(this->root, action);
+ while (found == NULL && count < 3) {
+ found = tdelete(&hash, &(this->root), hashDeleteComp);
+ if (found == NULL) {
+ puts("DEBUG: !!!!! NOT FOUND !!!!!!!");
+ void * found = hashGet(this, search, nsearch);
+ printf("DEBUG: find results in %p\n", found);
+ }
+ count++;
}
+ puts("===");
+ twalk(this->root, action);
- tdelete(&hash, &(this->root), hashDeleteComp);
-
- return (NULL != found)? found : NULL;
+ return found;
}
// vim: set ts=4 sw=4:
diff --git a/src/hash/get.c b/src/hash/get.c
index 2d64514..cebf06b 100644
--- a/src/hash/get.c
+++ b/src/hash/get.c
@@ -20,6 +20,8 @@
* along with this program. If not, see .
*/
+#include
+
#include
#include
@@ -37,10 +39,10 @@ hashGetComp(const void * a, const void * b)
void *
hashGet(Hash this, const char * search, size_t nsearch)
{
- unsigned long hash = sdbm((const unsigned char *)search, nsearch);
- void * found = tfind(&hash, &(this->root), hashGetComp);
+ unsigned long hash = sdbm((const unsigned char *)search, nsearch);
+ void ** found = tfind(&hash, &(this->root), hashGetComp);
- return (NULL != found)? *(void**)found : NULL;
+ return (NULL != found)? *found : NULL;
}
// vim: set ts=4 sw=4:
diff --git a/src/hash/interface/hashable.c b/src/hash/interface/hashable.c
index 0113388..6c0bc7f 100644
--- a/src/hash/interface/hashable.c
+++ b/src/hash/interface/hashable.c
@@ -37,7 +37,23 @@ hashableGetHash(void * hashable)
{
unsigned long ret;
- RETCALL(hashable, Hashable, getHash, ret);
+ //RETCALL(hashable, Hashable, getHash, ret);
+ do {
+ struct i_Hashable * iface;
+ //_CALL(GET_CLASS(hashable), Hashable, getHash);
+ do {
+ class_ptr class = GET_CLASS(hashable);
+ iface = (struct i_Hashable *)IFACE_GET(class, &i_Hashable);
+ while ((NULL == iface || NULL == iface->getHash) && HAS_PARENT(class)) {
+ class = class->parent;
+ iface = (struct i_Hashable *)IFACE_GET(class, &i_Hashable);
+ }
+ assert(NULL != iface->getHash);
+ } while(0);
+
+ ret = iface->getHash(hashable);
+ } while(0);
+
return ret;
}
diff --git a/src/http/message.c b/src/http/message.c
index 130338f..60837ac 100644
--- a/src/http/message.c
+++ b/src/http/message.c
@@ -65,6 +65,8 @@ httpMessageDtor(void * _this)
MEM_FREE(this->body);
} else {
assetPoolRelease(this->asset);
+ this->asset = NULL;
+ this->body = NULL;
}
}
diff --git a/src/http/response/asset.c b/src/http/response/asset.c
index de080ba..29e727a 100644
--- a/src/http/response/asset.c
+++ b/src/http/response/asset.c
@@ -55,10 +55,15 @@
HttpResponse
-httpResponseAsset(Asset asset)
+httpResponseAsset(const char * fname, size_t nfname)
{
HttpResponse response;
HttpMessage message;
+ Asset asset = assetPoolGet(fname, nfname);
+
+ if (NULL == asset) {
+ return NULL;
+ }
response = new(HttpResponse, "HTTP/1.1", 200, "OK");
message = (HttpMessage)response;
diff --git a/src/http/worker/get_asset.c b/src/http/worker/get_asset.c
index d833e0d..66fd0c5 100644
--- a/src/http/worker/get_asset.c
+++ b/src/http/worker/get_asset.c
@@ -41,7 +41,6 @@ httpWorkerGetAsset(
size_t nmatch;
HttpHeader header;
HttpMessage message;
- Asset asset;
size_t nfname = strlen(fname);
@@ -58,31 +57,25 @@ httpWorkerGetAsset(
nmatch = (header->nvalue)[0];
}
- asset = assetPoolGet(fname, nfname);
+ message = (HttpMessage)httpResponseAsset(fname, nfname);
- if (NULL == asset) {
+ if (NULL == message) {
return (HttpMessage)httpResponse404();
}
- if (asset->netag == nmatch
- && 0 == memcmp(asset->etag, match, asset->netag)) {
- assetPoolRelease(asset);
+ if (message->asset->netag == nmatch
+ && 0 == memcmp(message->asset->etag, match, nmatch)) {
+ HttpMessage new_message;
- return (HttpMessage)httpResponse304(
- asset->mime_type, asset->nmime_type,
- asset->etag, asset->netag,
- asset->mtime, asset->nmtime);
- }
+ new_message = (HttpMessage)httpResponse304(
+ message->asset->mime_type, message->asset->nmime_type,
+ message->asset->etag, message->asset->netag,
+ message->asset->mtime, message->asset->nmtime);
- message = (HttpMessage)httpResponseAsset(asset);
+ delete(message);
- if (NULL == message) {
- // here we should be somewhat more care about what causes
- // the message to be NULL... here this could be also a
- // 404 not found....
- assetPoolRelease(asset);
- message = (HttpMessage)httpResponse500();
- }
+ return new_message;
+ }
return message;
}
diff --git a/src/http/writer/write.c b/src/http/writer/write.c
index 0ca12d3..5c25aca 100644
--- a/src/http/writer/write.c
+++ b/src/http/writer/write.c
@@ -117,12 +117,8 @@ httpWriterWrite(void * _this, Stream st)
* By the way, the same is true for reading,
* so to say, the parser.
*/
- // cont = 0;
- // break;
-
- /* to go a step further...we send it to the
- * poll cicle again... */
- return -1;
+ cont = 0;
+ break;
}
if (this->written >= this->nheader + this->current->nbody) {
diff --git a/src/server/handle_accept.c b/src/server/handle_accept.c
index ab028b5..9253a7b 100644
--- a/src/server/handle_accept.c
+++ b/src/server/handle_accept.c
@@ -44,9 +44,10 @@ serverHandleAccept(Server this, unsigned int i)
}
acc = socketAccept((0 == i)? this->sock : this->sockSSL, &remoteAddr);
- socketNonblock(acc);
- if (-1 != acc->handle) {
+ if (NULL != acc && -1 != acc->handle) {
+ socketNonblock(acc);
+
switch(i) {
case 0:
// no SSL
@@ -82,21 +83,24 @@ serverHandleAccept(Server this, unsigned int i)
delete(acc);
switch(errno) {
- case EAGAIN:
+ case EAGAIN|EWOULDBLOCK:
+ case EINTR:
loggerLog(this->logger,
LOGGER_DEBUG,
"server accept blocks");
+ return -1;
break;
default:
loggerLog(this->logger,
LOGGER_DEBUG,
"server accept error");
+ return -2;
break;
}
}
- return (acc)? acc->handle : -1;
+ return acc->handle;
}
// vim: set ts=4 sw=4:
diff --git a/src/server/run.c b/src/server/run.c
index afdb648..c168437 100644
--- a/src/server/run.c
+++ b/src/server/run.c
@@ -51,7 +51,7 @@ serverRun(Server this)
* handle accept
*/
if (0 != ((this->fds)[0].revents & POLLIN)) {
- if (-1 == serverHandleAccept(this, 0)) {
+ if (0 > serverHandleAccept(this, 0)) {
events--;
}
}