http_reqdict_t *dict;
http_transport_t *transport;
ID flg;
+ ID sem;
};
+#define HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector) \
+ err = wai_sem((connector)->sem, T_FOREVER); \
+ if (err < 0) { \
+ return err; \
+ }
+#define HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_VOID(connector) \
+ err = wai_sem((connector)->sem, T_FOREVER); \
+ if (err < 0) { \
+ return; \
+ }
+#define HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector) \
+ sig_sem((connector)->sem);
+
#define HTTP_CONNECTOR_FLAG_CREARMASK(flag) (~(flag))
#define HTTP_CONNECTOR_FLAG_REQUEST 0x00000001
#define HTTP_CONNECTOR_FLAG_EVENT 0x00000002
ID id;
W err;
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
id = http_reqdict_allocate(connector->dict, host, host_len, port, method);
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
if (id < 0) {
DP_ER("http_reqdict_allocate", id);
return id; /* TODO */
{
http_reqentry_t *entry;
Bool transport_close = True;
+ W err;
+
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_VOID(connector);
entry = http_reqdict_getentrybyID(connector->dict, endpoint);
if (entry == NULL) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return;
}
}
http_reqdict_free(connector->dict, endpoint);
+
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
}
LOCAL W http_connector_searchwaiting(http_connector_t *connector)
return ret;
}
+LOCAL Bool http_connector_isexistwaiting(http_connector_t *connector)
+{
+ http_reqentry_t *entry;
+ http_recdictiterator_t iter;
+ Bool cont, ret = False;
+
+ http_reqdictiterator_initialize(&iter, connector->dict);
+ for (;;) {
+ cont = http_reqdictiterator_next(&iter, &entry);
+ if (cont == False) {
+ break;
+ }
+ if (entry->status == WAITING_TRANSPORT) {
+ ret = True;
+ break;
+ } else if (entry->status == SENDING_REQUEST) {
+ ret = True;
+ break;
+ } else if (entry->status == WAITING_RESPONSE) {
+ ret = True;
+ break;
+ } else if (entry->status == RECEIVING_RESPONSE) {
+ ret = True;
+ break;
+ }
+ }
+ http_reqdictiterator_finalize(&iter);
+
+ return ret;
+}
+
LOCAL W http_connector_waitreceiving(http_connector_t *connector, TMOUT tmout)
{
W ret = 0;
EXPORT W http_connector_waitconnection(http_connector_t *connector, TMOUT tmout)
{
W err;
- Bool evt = False;
+ Bool evt = False, exist;
+ err = wai_flg(connector->flg, HTTP_CONNECTOR_FLAG_REQUEST, WF_AND|NOCLR, tmout);
+ if (err < 0) {
+ return err;
+ }
+
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
err = http_connector_searchwaiting(connector);
if (err < 0) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return err;
}
if (err > 0) {
}
http_transport_releaseunusedendpoint(connector->transport);
+ exist = http_connector_isexistwaiting(connector);
+ if (exist == False) {
+ clr_flg(connector->flg, HTTP_CONNECTOR_FLAG_CLEARMASK_REQUEST);
+ }
+
err = http_connector_waitreceiving(connector, tmout);
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
if (err < 0) {
return err;
}
DP_ER("wai_flg", err);
return err;
}
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
found = http_connector_searcheventtarget(connector, event);
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
if (found == False) {
err = clr_flg(connector->flg, HTTP_CONNECTOR_FLAG_CLEARMASK_EVENT);
if (err < 0) {
Bool cont;
CONST UB *str;
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
+
HTTP_CONNECTOR_SENDXXX_GET_CHECK(connector, endpoint, SEND_REQUEST_LINE, entry);
err = http_requestlinestream_initialize(&reqline, entry->method, path, path_len);
if (err < 0) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return err;
}
for (;;) {
http_requestlinestream_finalize(&reqline);
if (err < 0) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return err;
}
entry->snd_state = SEND_HEADER_MINE;
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
+
return 0;
}
http_reqentry_t *entry;
W err;
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
+
HTTP_CONNECTOR_SENDXXX_GET_CHECK_2(connector, endpoint, SEND_HEADER_MINE, SEND_HEADER_USER, entry);
if (entry->snd_state == SEND_HEADER_MINE) {
err = http_connector_writedefaultheader(connector, entry->transport, entry->host, entry->host_len);
if (err < 0) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return err;
}
entry->snd_state = SEND_HEADER_USER;
}
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
+
return 0;
}
http_reqentry_t *entry;
W err;
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
+
HTTP_CONNECTOR_SENDXXX_GET_CHECK_2(connector, endpoint, SEND_HEADER_MINE, SEND_HEADER_USER, entry);
if (entry->snd_state == SEND_HEADER_MINE) {
err = http_connector_writedefaultheader(connector, entry->transport, entry->host, entry->host_len);
if (err < 0) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return err;
}
}
err = http_transport_write(connector->transport, entry->transport, "\r\n", 2);
if (err < 0) {
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
return err;
}
entry->snd_state = SEND_MESSAGE_BODY;
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
+
return 0;
}
http_reqentry_t *entry;
W err;
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
+
HTTP_CONNECTOR_SENDXXX_GET_CHECK(connector, endpoint, SEND_MESSAGE_BODY, entry);
err = http_transport_write(connector->transport, entry->transport, p, len);
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
if (err < 0) {
return err;
}
EXPORT W http_connector_sendmessagebodyend(http_connector_t *connector, ID endpoint)
{
http_reqentry_t *entry;
+ W err;
+
+ HTTP_CONNECTOR_ENTER_CRITICAL_SECTION_RET_ERR(connector);
HTTP_CONNECTOR_SENDXXX_GET_CHECK(connector, endpoint, SEND_MESSAGE_BODY, entry);
entry->status = WAITING_RESPONSE;
+ HTTP_CONNECTOR_LEAVE_CRITICAL_SECTION(connector);
+
return 0;
}
DP_ER("cre_flg", connector->flg);
goto error_flg;
}
+ connector->sem = cre_sem(1, SEM_EXCL|DELEXIT);
+ if (connector->sem < 0) {
+ DP_ER("cre_sem", connector->sem);
+ goto error_sem;
+ }
connector->transport = http_transport_new(10/*tmp*/);
if (connector->transport == NULL) {
DP_ER("http_transport_new", -1);
http_transport_delete(connector->transport);
error_transport:
+ del_sem(connector->sem);
+error_sem:
del_flg(connector->flg);
error_flg:
http_reqdict_delete(connector->dict);
EXPORT VOID http_connector_delete(http_connector_t *connector)
{
http_transport_delete(connector->transport);
+ del_sem(connector->sem);
del_flg(connector->flg);
http_reqdict_delete(connector->dict);
free(connector);