1fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <alloca.h> 2fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <errno.h> 3a744b05984a963966cec08758ffe582d241be9d7Elliott Hughes#include <malloc.h> 4fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <pthread.h> 54389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn#include <signal.h> 6d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat#include <string.h> 77bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun#include <arpa/inet.h> 84389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn#include <sys/socket.h> 94389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn#include <sys/types.h> 10fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 11fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#define LOG_TAG "SocketClient" 12fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <cutils/log.h> 13fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 14fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat#include <sysutils/SocketClient.h> 15fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 168702bb17f40022e970e8acd40b348d074e39afc7Robert GreenwaltSocketClient::SocketClient(int socket, bool owned) { 178702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt init(socket, owned, false); 188702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt} 198702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt 208702bb17f40022e970e8acd40b348d074e39afc7Robert GreenwaltSocketClient::SocketClient(int socket, bool owned, bool useCmdNum) { 218702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt init(socket, owned, useCmdNum); 228702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt} 238702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt 248702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwaltvoid SocketClient::init(int socket, bool owned, bool useCmdNum) { 258702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mSocket = socket; 268702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mSocketOwned = owned; 278702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mUseCmdNum = useCmdNum; 28fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat pthread_mutex_init(&mWriteMutex, NULL); 29648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick pthread_mutex_init(&mRefCountMutex, NULL); 308702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mPid = -1; 318702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mUid = -1; 328702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mGid = -1; 338702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mRefCount = 1; 348702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt mCmdNum = 0; 3530abb7234de2a9caa1add4b00a189436f0b24560Kenny Root 3630abb7234de2a9caa1add4b00a189436f0b24560Kenny Root struct ucred creds; 3730abb7234de2a9caa1add4b00a189436f0b24560Kenny Root socklen_t szCreds = sizeof(creds); 3830abb7234de2a9caa1add4b00a189436f0b24560Kenny Root memset(&creds, 0, szCreds); 3930abb7234de2a9caa1add4b00a189436f0b24560Kenny Root 4030abb7234de2a9caa1add4b00a189436f0b24560Kenny Root int err = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &creds, &szCreds); 4130abb7234de2a9caa1add4b00a189436f0b24560Kenny Root if (err == 0) { 4230abb7234de2a9caa1add4b00a189436f0b24560Kenny Root mPid = creds.pid; 4330abb7234de2a9caa1add4b00a189436f0b24560Kenny Root mUid = creds.uid; 4430abb7234de2a9caa1add4b00a189436f0b24560Kenny Root mGid = creds.gid; 4530abb7234de2a9caa1add4b00a189436f0b24560Kenny Root } 46fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 47fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat 484389588e8ded66148d9e616aa20307cf25144460Mark SalyzynSocketClient::~SocketClient() { 494520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang if (mSocketOwned) { 504520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang close(mSocket); 514520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang } 524520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang} 534520246d3534c087f3e9253c34f99dd1e45b7bd7Xianzhu Wang 54db017545796747115b8797f03e662b0f398a7c7bSan Mehatint SocketClient::sendMsg(int code, const char *msg, bool addErrno) { 558702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt return sendMsg(code, msg, addErrno, mUseCmdNum); 568702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt} 578702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt 588702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwaltint SocketClient::sendMsg(int code, const char *msg, bool addErrno, bool useCmdNum) { 59d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat char *buf; 608702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt int ret = 0; 6103f0d27f6c49530a91402ed42f8ca4b2fda04b9fSan Mehat 62d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat if (addErrno) { 638702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt if (useCmdNum) { 648702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt ret = asprintf(&buf, "%d %d %s (%s)", code, getCmdNum(), msg, strerror(errno)); 658702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt } else { 668702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt ret = asprintf(&buf, "%d %s (%s)", code, msg, strerror(errno)); 678702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt } 68d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat } else { 698702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt if (useCmdNum) { 708702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt ret = asprintf(&buf, "%d %d %s", code, getCmdNum(), msg); 718702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt } else { 728702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt ret = asprintf(&buf, "%d %s", code, msg); 738702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt } 74d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat } 7523f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn // Send the zero-terminated message 768702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt if (ret != -1) { 778702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt ret = sendMsg(buf); 788702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt free(buf); 798702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt } 808702bb17f40022e970e8acd40b348d074e39afc7Robert Greenwalt return ret; 81d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat} 82d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat 8323f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn// send 3-digit code, null, binary-length, binary data 847bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurunint SocketClient::sendBinaryMsg(int code, const void *data, int len) { 857bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 8623f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn // 4 bytes for the code & null + 4 bytes for the len 877599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt char buf[8]; 8823f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn // Write the code 897599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt snprintf(buf, 4, "%.3d", code); 9023f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn // Write the len 917bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun uint32_t tmp = htonl(len); 927599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt memcpy(buf + 4, &tmp, sizeof(uint32_t)); 937bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 9423f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn struct iovec vec[2]; 9523f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn vec[0].iov_base = (void *) buf; 9623f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn vec[0].iov_len = sizeof(buf); 9723f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn vec[1].iov_base = (void *) data; 9823f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn vec[1].iov_len = len; 9923f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn 1007bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun pthread_mutex_lock(&mWriteMutex); 10123f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn int result = sendDataLockedv(vec, (len > 0) ? 2 : 1); 1027bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun pthread_mutex_unlock(&mWriteMutex); 1037bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 1047bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun return result; 1057bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun} 1067bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 1077bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun// Sends the code (c-string null-terminated). 1087bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurunint SocketClient::sendCode(int code) { 1097599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt char buf[4]; 1107599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt snprintf(buf, sizeof(buf), "%.3d", code); 1117599bfcf13cf022333338b7a87aaddae69c48d73Robert Greenwalt return sendData(buf, sizeof(buf)); 1127bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun} 1137bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 114594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwaltchar *SocketClient::quoteArg(const char *arg) { 115594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt int len = strlen(arg); 116594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt char *result = (char *)malloc(len * 2 + 3); 117594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt char *current = result; 118594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt const char *end = arg + len; 119544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li char *oldresult; 120544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li 121544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li if(result == NULL) { 122544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li SLOGW("malloc error (%s)", strerror(errno)); 123544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li return NULL; 124544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li } 125594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt 126594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt *(current++) = '"'; 127594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt while (arg < end) { 128594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt switch (*arg) { 129594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt case '\\': 130594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt case '"': 131594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt *(current++) = '\\'; // fallthrough 132594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt default: 133594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt *(current++) = *(arg++); 134594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt } 135594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt } 136594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt *(current++) = '"'; 137594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt *(current++) = '\0'; 138544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li oldresult = result; // save pointer in case realloc fails 139594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt result = (char *)realloc(result, current-result); 140544a7f7a36cb9434505fe5cdc9e79d16937ac23fHong-Mei Li return result ? result : oldresult; 141594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt} 142594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt 143594947793c98e8e7f58f0e9b2cb962c9ef23adebRobert Greenwalt 144db017545796747115b8797f03e662b0f398a7c7bSan Mehatint SocketClient::sendMsg(const char *msg) { 145c73a3a5771a2d29d1bae666bfde12f751d66fc96San Mehat // Send the message including null character 1468c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick if (sendData(msg, strlen(msg) + 1) != 0) { 1478c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick SLOGW("Unable to send msg '%s'", msg); 1488c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick return -1; 1498c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick } 1508c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick return 0; 1518c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick} 1528c5669f9f9a228efebf4059fd4ceace5cece578bBrad Fitzpatrick 1537bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurunint SocketClient::sendData(const void *data, int len) { 15423f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn struct iovec vec[1]; 15523f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn vec[0].iov_base = (void *) data; 15623f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn vec[0].iov_len = len; 1577bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 1587bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun pthread_mutex_lock(&mWriteMutex); 15923f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn int rc = sendDataLockedv(vec, 1); 1607bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun pthread_mutex_unlock(&mWriteMutex); 1617bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 1627bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun return rc; 1637bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun} 1647bf4c45f842ded6d6ad6b2d80e052ddf56969723Selim Gurun 16523f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzynint SocketClient::sendDatav(struct iovec *iov, int iovcnt) { 16623f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn pthread_mutex_lock(&mWriteMutex); 16723f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn int rc = sendDataLockedv(iov, iovcnt); 16823f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn pthread_mutex_unlock(&mWriteMutex); 16923f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn 17023f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn return rc; 17123f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn} 17223f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn 17323f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzynint SocketClient::sendDataLockedv(struct iovec *iov, int iovcnt) { 174d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat 1752e5fcd08ac177e984ebf1fb05bab5dfcf296c5a4Mattias Falk if (mSocket < 0) { 1762e5fcd08ac177e984ebf1fb05bab5dfcf296c5a4Mattias Falk errno = EHOSTUNREACH; 1772e5fcd08ac177e984ebf1fb05bab5dfcf296c5a4Mattias Falk return -1; 1782e5fcd08ac177e984ebf1fb05bab5dfcf296c5a4Mattias Falk } 1792e5fcd08ac177e984ebf1fb05bab5dfcf296c5a4Mattias Falk 18023f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn if (iovcnt <= 0) { 18116ae478af46100a435c2875afa020721a59a411aBrad Fitzpatrick return 0; 18216ae478af46100a435c2875afa020721a59a411aBrad Fitzpatrick } 18316ae478af46100a435c2875afa020721a59a411aBrad Fitzpatrick 1844389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn int ret = 0; 1854389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn int e = 0; // SLOGW and sigaction are not inert regarding errno 18623f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn int current = 0; 18723f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn 1884389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn struct sigaction new_action, old_action; 1894389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn memset(&new_action, 0, sizeof(new_action)); 1904389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn new_action.sa_handler = SIG_IGN; 1914389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn sigaction(SIGPIPE, &new_action, &old_action); 1924389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn 19323f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn for (;;) { 1944389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn ssize_t rc = TEMP_FAILURE_RETRY( 1954389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn writev(mSocket, iov + current, iovcnt - current)); 1964389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn 197af61509b50bc110b0c7c4691e37873cc0987ab5cDavid 'Digit' Turner if (rc > 0) { 19823f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn size_t written = rc; 19923f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn while ((current < iovcnt) && (written >= iov[current].iov_len)) { 20023f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn written -= iov[current].iov_len; 20123f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn current++; 20223f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn } 20323f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn if (current == iovcnt) { 20423f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn break; 20523f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn } 20623f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn iov[current].iov_base = (char *)iov[current].iov_base + written; 20723f04107dcedcef22556c1f57502cdddbfa2663fMark Salyzyn iov[current].iov_len -= written; 208af61509b50bc110b0c7c4691e37873cc0987ab5cDavid 'Digit' Turner continue; 209af61509b50bc110b0c7c4691e37873cc0987ab5cDavid 'Digit' Turner } 210af61509b50bc110b0c7c4691e37873cc0987ab5cDavid 'Digit' Turner 211af61509b50bc110b0c7c4691e37873cc0987ab5cDavid 'Digit' Turner if (rc == 0) { 2124389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn e = EIO; 2137e8529a8b528fd30586aa037f15a31b29582c537San Mehat SLOGW("0 length write :("); 214af61509b50bc110b0c7c4691e37873cc0987ab5cDavid 'Digit' Turner } else { 2154389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn e = errno; 2164389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn SLOGW("write error (%s)", strerror(e)); 217d768066ef54270a0d3ccfccd50ae8238db5a2cddSan Mehat } 2184389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn ret = -1; 2194389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn break; 220fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat } 2214389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn 2224389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn sigaction(SIGPIPE, &old_action, &new_action); 2234389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn 224f6b62d0a7d448e2685ef9afd934148943dc25a35Elliott Hughes if (e != 0) { 2254df4dfedf6beef891d05d4e80704f5f4a594a885Bo Huang errno = e; 226f6b62d0a7d448e2685ef9afd934148943dc25a35Elliott Hughes } 2274389588e8ded66148d9e616aa20307cf25144460Mark Salyzyn return ret; 228fa644ffe944c01a9b00f8d7676d58394fabee285San Mehat} 229648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick 230648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrickvoid SocketClient::incRef() { 2314be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick pthread_mutex_lock(&mRefCountMutex); 2324be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick mRefCount++; 2334be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick pthread_mutex_unlock(&mRefCountMutex); 234648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick} 235648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick 2364be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrickbool SocketClient::decRef() { 2374be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick bool deleteSelf = false; 2384be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick pthread_mutex_lock(&mRefCountMutex); 2394be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick mRefCount--; 2404be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick if (mRefCount == 0) { 2414be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick deleteSelf = true; 2424be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick } else if (mRefCount < 0) { 2434be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick SLOGE("SocketClient refcount went negative!"); 2444be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick } 2454be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick pthread_mutex_unlock(&mRefCountMutex); 2464be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick if (deleteSelf) { 2474be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick delete this; 2484be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick } 2494be4e69f0128b7d9b0a29651ef4b79d806ae3ce7Brad Fitzpatrick return deleteSelf; 250648ebad883e7825353c841950dd7d78664c238e6Brad Fitzpatrick} 251