Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bce6f29 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow reregistering callback"

parents 33df4dbe 6e718f9e
Loading
Loading
Loading
Loading
+45 −5
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <assert.h>
#include <dirent.h>
#include <iostream>
#include <fstream>
@@ -34,6 +35,9 @@ namespace usb {
namespace V1_0 {
namespace implementation {

// Set by the signal handler to destroy the thread
volatile bool destroyThread;

int32_t readFile(std::string filename, std::string& contents) {
    std::ifstream file(filename);

@@ -374,7 +378,7 @@ void* work(void* param) {
        goto error;
    }

    while (1) {
    while (!destroyThread) {
        struct epoll_event events[64];

        nevents = epoll_wait(epoll_fd, events, 64, -1);
@@ -392,6 +396,7 @@ void* work(void* param) {
        }
    }

    ALOGI("exiting worker thread");
error:
    close(uevent_fd);

@@ -401,24 +406,59 @@ error:
    return NULL;
}

void sighandler(int sig)
{
    if (sig == SIGUSR1) {
        destroyThread = true;
        ALOGI("destroy set");
        return;
    }
    signal(SIGUSR1, sighandler);
}

Return<void> Usb::setCallback(const sp<IUsbCallback>& callback) {

    if (mCallback != NULL) {
        ALOGE("Callback already registered");
    pthread_mutex_lock(&mLock);
    if ((mCallback == NULL && callback == NULL) ||
            (mCallback != NULL && callback != NULL)) {
        mCallback = callback;
        pthread_mutex_unlock(&mLock);
        return Void();
    }

    mCallback = callback;
    ALOGI("registering callback");

    if (mCallback == NULL) {
        if  (!pthread_kill(mPoll, SIGUSR1)) {
            pthread_join(mPoll, NULL);
            ALOGI("pthread destroyed");
        }
        pthread_mutex_unlock(&mLock);
        return Void();
    }

    destroyThread = false;
    signal(SIGUSR1, sighandler);

    if (pthread_create(&mPoll, NULL, work, this)) {
        ALOGE("pthread creation failed %d", errno);
        mCallback = NULL;
    }
    pthread_mutex_unlock(&mLock);
    return Void();
}

    return Void();
// Protects *usb assignment
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
Usb *usb;

Usb::Usb() {
    pthread_mutex_lock(&lock);
    // Make this a singleton class
    assert(usb == NULL);
    usb = this;
    pthread_mutex_unlock(&lock);
}

}  // namespace implementation
+2 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ using ::android::hardware::Void;
using ::android::sp;

struct Usb : public IUsb {
    Usb();
    Return<void> switchRole(const hidl_string& portName, const PortRole& role) override;
    Return<void> setCallback(const sp<IUsbCallback>& callback) override;
    Return<void> queryPortStatus() override;
@@ -39,6 +40,7 @@ struct Usb : public IUsb {
    sp<IUsbCallback> mCallback;
    private:
        pthread_t mPoll;
        pthread_mutex_t mLock = PTHREAD_MUTEX_INITIALIZER;
};

}  // namespace implementation